GlobalNetworkPolicy: one default-deny for the whole cluster

GlobalNetworkPolicy: one default-deny for the whole cluster

The namespaced policies so far each guarded a single namespace. A GlobalNetworkPolicy is cluster-scoped: one object can flip every namespaced pod - prod and dev together - to default-deny, then hand back the flows you trust. This is the zero-trust baseline every later lesson tightens.

What you'll learn

What is a GlobalNetworkPolicy?

A GlobalNetworkPolicy (projectcalico.org/v3) is the cluster-scoped sibling of the Calico NetworkPolicy. It carries the same rule grammar - same actions, selectors, ports, L7 - but drops the namespace boundary and adds a few fields that only make sense cluster-wide:

Calico NetworkPolicy GlobalNetworkPolicy
Scope one namespace whole cluster (no metadata.namespace)
Namespace targeting implicit (its own ns) spec.namespaceSelector - pick which namespaces' pods it governs
Can apply to host interfaces? no yes - it can select HostEndpoints, not just pods
Host/dataplane modifiers doNotTrack, preDNAT, applyOnForward

The additions:

Everything else - order, tier, serviceAccountSelector, the whole rule grammar - is identical to the Calico NetworkPolicy you already know.

The policy

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: cluster-default-deny-allow-web-to-app
spec:
  order: 1001
  namespaceSelector: has(projectcalico.org/name)
  types:
    - Ingress
    - Egress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: tier == 'web'
      destination:
        selector: tier == 'app'
        ports: [8080]
  egress:
    - action: Allow
      protocol: TCP
      source:
        selector: tier == 'web'
      destination:
        selector: tier == 'app'
        ports: [8080]

Why default-deny first

It's tempting to "deny the bad stuff," but you can't enumerate everything bad. Flip the whole cluster to deny, then justify each flow you add back - now an omission fails closed, not open.

Safe rollout tip: the first cluster-wide deny is the scariest change you'll make. In production you'd preview it as a staged policy before enforcing - that's lesson 85.

What to observe

Allowed

Denied

The trap: this carve-out keys on tier, not env, so dev/frontend → prod/backend is also allowed - the policy never said the two ends must share an environment. Cluster-wide selectors are powerful and easy to make too broad. Tightening the prod/dev boundary is a job for sharper selectors (and the next few lessons).

Recap

One GlobalNetworkPolicy is a cluster-wide default-deny with a carve-out - the foundation of zero trust. But a real default-deny breaks one thing immediately: name resolution. Next, the one egress every pod still needs - DNS.