Learn Calico - Zero Trust Security (Default Deny & Microsegmentation)
Series/Learn Calico/Episode 13
Episode 13 of 23

Learn Calico - Zero Trust Security (Default Deny & Microsegmentation)

This episode covers zero trust security with Calico: building default-deny per namespace and per pod, label-based microsegmentation, modeling workload endpoints, and the principles of zero trust in Kubernetes networking.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Zero trust is a simple principle with an implementation that demands discipline: don't trust anything by default, verify every connection. In the Kubernetes networking context, that means no workload can talk to another workload unless explicitly allowed.

In episode 13 we translate that principle into Calico practice: default-deny at the namespace and pod level, microsegmentation with labels, and modeling workload endpoints as the security unit. You'll leave this episode with a pattern you can use directly as a cluster baseline.

Zero Trust Principles in Networking

Placing the Trust Boundaries

In a cluster without policy, every pod can reach every other pod — there are no boundaries. Zero trust places boundaries at several points: namespaces (boundary between teams), labels (boundary between applications), and ports (boundary between functions). All three layers can be enabled together with Calico.

Default Deny as the Foundation

The first step of zero trust is ensuring that without explicit policy, there is no traffic. In episode 6 we created a global deny with GlobalNetworkPolicy. In this episode we apply it more granularly: default-deny per namespace.

Default Deny per Namespace

Policy per Namespace

To close an entire namespace at once:

Namespace default deny
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: payments
spec:
  selector: all()
  types:
    - Ingress
    - Egress
  ingress: []
  egress: []

This policy matches every pod in the payments namespace, then with no rules at all — the result is all inbound and outbound traffic is denied. Teams that want to open access add an Allow policy in the appropriate tier.

Gradual Activation Flow

Applying default deny to the whole cluster at once is scary. Here's the recommended gradual activation:

Gradual default deny activation
kubectl label ns payments policy.open=true
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: payments
spec:
  selector: all()
  types:
    - Ingress
    - Egress
  ingress: []
  egress: []
EOF
calicoctl get networkpolicy -n payments

Start namespace by namespace, watch the alarms, then scale to the whole cluster.

Microsegmentation with Labels

Dividing Workloads with Labels

Microsegmentation means breaking the network into small label-based segments. Here's a security model example for a payments application:

  • tier: web can only receive from the ingress controller.
  • tier: api only receives from tier: web and exits to tier: db.
  • tier: db only receives from tier: api on the database port.
Inter-tier policy
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: api-allow-web
  namespace: payments
spec:
  selector: tier == 'api'
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: tier == 'web'
      destination:
        ports:
          - 8080

This policy only allows tier: web to reach tier: api on port 8080. Other traffic is denied by the namespace default deny.

Workload Endpoints as the Security Unit

All of this works because every pod is represented as a workload endpoint with its pod's labels. When a pod gets a new label, the policies using that label apply automatically — no restart and no manual edits:

View endpoints as security units
calicoctl get workloadendpoints -n payments -o wide
kubectl label pod api-pod-xyz tier=api
calicoctl get workloadendpoints -n payments -o wide | grep api-pod

calicoctl get workloadendpoints -o wide shows the endpoints with their labels and nodes. Label changes are immediately reflected in the endpoints.

Modeling Legitimate Connection Flows

Inventory the Flows First

Before writing policy, map the legitimate connection flows. For each workload pair, write: source, destination, port, and protocol. From this inventory, each row becomes one Allow rule. The resulting policy is concise and auditable:

Payments flow inventory
ingress-nginx  -> tier:web    (TCP 80, 443)
tier:web       -> tier:api    (TCP 8080)
tier:api       -> tier:db     (TCP 5432)
tier:api       -> kube-dns    (UDP 53)
tier:api       -> api.external.example.com (TCP 443)

Writing Policies That Match the Inventory

From the inventory above, each row becomes a NetworkPolicy or a rule within a larger policy. Don't forget the DNS row — without it, domain egress (episode 11) and ordinary resolution will fail.

Testing the Effectiveness of Zero Trust

Test from Outside the Boundaries

After the policies are applied, test with a pod that should be denied:

Test traffic denial
kubectl run intruder --image=busybox -n payments --command -- sleep 3600
kubectl exec -n payments intruder -- wget -T 3 -q -O - http://api:8080
kubectl exec -n payments deploy/api -- wget -T 3 -q -O - http://db:5432

Both commands should time out. If they succeed, there's an Allow policy that's too broad — audit the rules and narrow their selectors.

Audit with Flow Logs

To see the decisions the dataplane made during testing:

Audit policy decisions
kubectl logs -n calico-system ds/calico-node | grep -iE "deny|drop" | tail -20

Conclusion

Episode 13 turns the zero trust principle into actionable policy: default-deny per namespace and per pod, label-based microsegmentation, and modeling workload endpoints as the security unit.

Key takeaways:

  • Zero trust = default deny at every level, then open only what's legitimate.
  • A policy with ingress: [] and egress: [] closes a namespace.
  • Gradual activation namespace by namespace reduces risk.
  • Microsegmentation uses labels like tier as segments.
  • Workload endpoints reflect pod labels in real time.
  • Inventory the connection flows first, then write the policy.

In the next episode, episode 14, we cover host endpoints and node security — protecting the Kubernetes nodes themselves with HostEndpoint, locking down management ports, and applying policy to node-bound and inter-node traffic.

Learn Calico - Zero Trust Security (Default Deny & Microsegmentation) | Learn Calico