Open-Source Wikis

/

Cilium

/

Features

/

Network policy

cilium/cilium

Network policy

Active contributors: jrajahalme, christarazi, joestringer, aanm, gandro

Purpose

Cilium enforces network policy on every packet. Three policy formats are accepted simultaneously:

  • Kubernetes NetworkPolicy (built-in API).
  • CiliumNetworkPolicy (CNP) — namespaced, richer than NetworkPolicy. Supports L7, FQDN, deny rules.
  • CiliumClusterwideNetworkPolicy (CCNP) — cluster-scoped, otherwise identical to CNP.

The agent compiles all three into a single in-memory representation and produces per-endpoint policy maps that the dataplane consults on every packet.

Directory layout

pkg/policy/
├── api/                       # the public CNP/CCNP/NetworkPolicy types and validators
├── repository.go              # in-memory rule database
├── selectorcache.go           # compiled selectors -> identity sets
├── distillery.go              # compute SelectorPolicy per endpoint
├── l4.go                      # L4 entry construction
├── l7policy.go                # L7 metadata propagation
├── policymap/                 # writes the per-endpoint BPF policy map
├── correlation/               # correlation between policy + traffic
└── cells.go

pkg/policy/api/                # the policy schema (CRD types)
pkg/k8s/apis/cilium.io/v2/cnp_types.go  # the CRD wrapper
pkg/proxy/                     # L7 redirect runtime (Envoy / DNS)
pkg/fqdn/                      # FQDN policy (DNS proxy + ipcache updates)
pkg/maps/policymap/            # the policy BPF map

Policy model

A rule has three parts:

  • Endpoint selector — which endpoints the rule applies to (label selector → set of identities).
  • Ingress / egress lists — for each direction, a list of allow rules.
  • Each rule carries L3 (fromEndpoints, toEndpoints, fromCIDR, toCIDR, toFQDNs, fromEntities), L4 (toPorts), and optionally L7 (http, kafka, dns, custom).

Rules are additive: any rule that allows a flow makes it allowed. Deny rules (ingressDeny / egressDeny) override allow rules and are evaluated first.

Default mode is default-allow if no policy matches; once any policy applies to an endpoint, the endpoint becomes default-deny for that direction. Behaviour matches Kubernetes NetworkPolicy semantics.

Compilation pipeline

graph LR
    CRD[CiliumNetworkPolicy CRD]
    API[NetworkPolicy core API]
    Repo[Policy Repository<br/>pkg/policy/repository.go]
    SC[SelectorCache<br/>pkg/policy/selectorcache.go]
    Distillery[Distillery<br/>pkg/policy/distillery.go]
    SP[SelectorPolicy<br/>per identity]
    EP[Endpoint<br/>pkg/endpoint]
    PMap[policy map<br/>pkg/maps/policymap]

    CRD --> Repo
    API --> Repo
    Repo --> SC
    Repo --> Distillery
    SC --> Distillery
    Distillery --> SP
    SP --> EP
    EP --> PMap

Steps:

  1. Watch — k8s watchers (pkg/k8s/watchers/cnp.go, policy.go) push CRDs into the repository.
  2. SelectorCache — every label selector is compiled into a set of identities; when identities change, dependents get notified.
  3. Distillery — for each (identity, traffic-direction) combination, produce a SelectorPolicy that is the merged set of allowed L4 entries and L7 redirects.
  4. Endpoint — per-endpoint goroutine consumes the SelectorPolicy and writes the per-endpoint policy map plus L7 redirects.
  5. Datapathbpf/lib/policy.h looks up the policy map by (identity, port, proto, direction) on every packet.

L7 enforcement

When a rule includes an L7 stanza (HTTP method, gRPC method, Kafka topic, DNS pattern), the policy map entry is marked as redirect to the L7 proxy. The dataplane TPROXYs the connection to Envoy (or to the DNS proxy for DNS), which makes the L7 verdict and writes a structured access log that Hubble parses into a flow.

See systems/envoy-l7-proxy.md.

FQDN (toFQDNs)

toFQDNs: ["api.example.com"] lets policy reference DNS names. The DNS proxy (in-agent at pkg/fqdn/, or the optional out-of-process standalone-dns-proxy) intercepts DNS responses for the source pod and:

  1. Records the IP set associated with the FQDN.
  2. Adds those IPs to the ipcache with a synthetic identity.
  3. Emits a policy map entry that allows the source identity → that synthetic identity.

A garbage collector (pkg/fqdn/dnsproxy/) ages out IPs that no longer match a recent DNS response.

Deny rules

Deny rules are stored separately in the policy map and consulted first. They are useful for "always block" patterns and for compliance: e.g., deny all egress to a list of CIDRs even if other policies allow.

Testing

  • Unit tests: pkg/policy/*_test.go covering distillery, selector cache, repository.
  • Compatibility tests: pkg/policy/k8s/ ensures Kubernetes NetworkPolicy semantics are matched.
  • Connectivity test: cilium-cli connectivity test exercises a battery of scenarios across L3/L4/L7/FQDN/deny/CIDR.

Key source files

File Purpose
pkg/policy/repository.go Rule database.
pkg/policy/selectorcache.go Compiled selectors.
pkg/policy/distillery.go Per-identity SelectorPolicy.
pkg/policy/policymap/policymap.go BPF map.
pkg/policy/api/rule.go Public rule type.
pkg/fqdn/dnsproxy/proxy.go DNS proxy.
pkg/proxy/envoyproxy.go Envoy redirect registration.
bpf/lib/policy.h Dataplane lookup.

See systems/identity-allocation.md for the identity model that policy is expressed against.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Network policy – Cilium wiki | Factory