PRACTITIONER GUIDE
Practitioner Guide12 min read

Cilium Kubernetes Network Policy: L3/L4/L7 Policy Configuration, Hubble Observability, and Zero-Trust Pod-to-Pod Traffic

L7
HTTP-aware policy depth that Cilium provides natively via eBPF, enabling method and path restrictions not possible with standard Kubernetes NetworkPolicy which stops at L4
Default-deny
network policy baseline that blocks all pod-to-pod and pod-to-external traffic unless explicitly allowed, which the CiliumClusterwideNetworkPolicy resource can enforce across the entire cluster
toFQDNs
Cilium policy rule type that allows egress to specific domain names (api.stripe.com, s3.amazonaws.com) rather than IP ranges, which DNS resolves dynamically so policy stays accurate as cloud IPs rotate
Hubble
Cilium's built-in network observability layer that provides real-time L3/L4/L7 flow data for every pod-to-pod communication, enabling policy gap analysis without packet capture or sidecar overhead

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Standard Kubernetes NetworkPolicy stops at L4 — it can block or allow based on IP, port, and namespace, but it cannot distinguish between a GET /health request and a POST /admin/delete-all request to the same service on the same port. For internal service-to-service traffic in a zero-trust Kubernetes environment, L4 policy is often insufficient: a compromised pod that has an allowed egress path to another service can call any endpoint on that service with any HTTP method.

Cilium extends Kubernetes network policy to L7 using eBPF, without requiring a sidecar proxy. A CiliumNetworkPolicy can restrict the backend service to accept only POST requests to /api/v1/orders from the order service pod, blocking all other HTTP methods and paths even from pods with allowed L4 connectivity. Hubble provides the flow observability that makes policy development practical — rather than guessing what traffic a pod generates, you observe actual flows and write allow policies based on what you see. The combination of L7 policy enforcement and Hubble observability is what makes Cilium the CNI choice for teams implementing Kubernetes zero-trust networking.

Policy authoring: writing CiliumNetworkPolicy for real workloads

Writing effective CiliumNetworkPolicy starts with observing actual traffic flows rather than guessing from application documentation. Deploy in audit mode first to capture what traffic each pod actually generates, then write allow policies that match the observed traffic patterns, then switch to enforce mode. This observe-then-enforce pattern avoids the common failure of writing policies from documentation that miss runtime traffic patterns like health check calls, metadata service calls, and service discovery queries that applications make automatically.

Use Hubble observe in audit mode to capture real traffic before writing allow policies

Enable Cilium's policy audit mode with cilium config set policy-audit-mode=true before deploying any CiliumNetworkPolicy. In audit mode, Cilium logs what would be dropped by policies without actually dropping it, allowing you to observe the full traffic profile of each pod without breaking connectivity. Run hubble observe --namespace production --follow --output json for 24 hours across a representative workload period to capture all traffic patterns including startup sequences, health checks, periodic batch jobs, and failure recovery paths. Extract the unique source-destination-port-protocol tuples from the flow logs and use them as the basis for your allow policy rules. This eliminates the trial-and-error cycle of deploying a policy, breaking something, debugging what broke, updating the policy, and repeating.

Write DNS-based egress policy for cloud service egress rather than IP CIDR allowlists

Cloud service IP ranges change frequently and are too broad to use as meaningful security controls — an allowlist for *.amazonaws.com would include thousands of IP addresses covering hundreds of services. Use toFQDNs rules to allow egress to specific AWS service endpoints like s3.us-east-1.amazonaws.com, secretsmanager.us-east-1.amazonaws.com, and sts.amazonaws.com by name, which Cilium resolves dynamically and enforces at L4. If the application calls a specific API like api.pagerduty.com or api.slack.com, use matchName to allow exactly that domain rather than allowing broad *.pagerduty.com. The toFQDNs approach shrinks the effective attack surface for egress — a compromised pod can only reach the specific cloud services it was explicitly allowed to call, not the full IP range of any cloud provider.

Observability: Hubble for policy debugging and incident investigation

Hubble provides the network observability that makes Cilium's policies operationally maintainable. Without visibility into what traffic flows and what gets dropped, policy changes require educated guesses about their downstream effects. Hubble's real-time flow data — available through the CLI, the graphical UI, and as Prometheus metrics — makes network policy changes verifiable and makes incident investigation faster by showing exactly what network communication a compromised pod attempted.

Configure Hubble metrics in Prometheus to alert on unexpected egress policy drops

Enable Hubble Prometheus metrics with the cilium Helm chart parameter hubble.metrics.enabled=[drop,tcp,flow,port-distribution,icmp,http] which exposes a hubble_drop_total metric labeled by reason, source, and destination. Create a Prometheus alert that fires when hubble_drop_total increases significantly for any specific source pod identity within a short time window, which indicates either a broken policy configuration or a compromised pod attempting to reach denied destinations. A legitimate workload in steady state generates a predictable and stable drop rate; a spike in drops from a specific pod identity is a signal worth investigating. Route these alerts to the security team alongside application alerts so they are visible in incident response rather than buried in infrastructure metrics.

Use Hubble CLI for real-time incident investigation when a pod compromise is suspected

During a security incident where a Kubernetes pod is suspected of being compromised, Hubble provides immediate network-layer visibility without requiring packet capture setup or tcpdump on the node. Run hubble observe --pod suspicious-namespace/suspicious-pod --follow --output json to stream all network flows from the suspect pod in real time, including HTTP requests with method, path, and response codes for HTTP traffic. Look for egress connections to external IPs not matching any known service, POST requests to paths the application is not supposed to call, or high-frequency connection attempts to internal services suggesting lateral movement scanning. Hubble's flow logs persist for a configurable retention period (default 4096 flows in memory), so historical flows can be reviewed for the time period before the incident was detected.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

The bottom line

Cilium extends Kubernetes network security from L4 port/IP filtering to L7 HTTP method and path enforcement using eBPF, without the overhead and complexity of a service mesh sidecar. Implement network policy in three phases: observe actual traffic flows with Hubble in audit mode first, write CiliumNetworkPolicy allow rules based on observed flows (using toFQDNs for external egress rather than IP ranges), then switch to enforce mode. Apply a CiliumClusterwideNetworkPolicy default-deny baseline to ensure all pod communication requires explicit policy approval. Use Hubble CLI and Prometheus metrics to monitor policy drops, alert on unexpected egress attempts, and investigate suspected pod compromises with real-time flow data. L7 HTTP policy enforcement for service-to-service communication eliminates the coarse-grained trust that L4-only policy leaves in place.

Frequently asked questions

How do I write a basic CiliumNetworkPolicy to restrict pod egress?

Write a CiliumNetworkPolicy that restricts egress for a pod selector by defining the endpointSelector that matches the pods you want to control and an egress section that lists only the allowed destinations. For a backend API pod that should only reach the database on port 5432 and the metrics endpoint on port 9090, the policy selects the API pods with endpointSelector: matchLabels: app: api and defines egress rules: one rule to pods with app: postgres on port 5432, and one rule to pods with app: prometheus on port 9090. Any other egress from the API pods — outbound HTTP to the internet, calls to other services in the cluster — is denied by the policy. CiliumNetworkPolicy rules follow the same logic as standard Kubernetes NetworkPolicy: specifying any egress rule creates an implicit default-deny for all egress not matched by a rule, so the first rule you add may block previously working traffic.

How do I configure L7 HTTP policy to restrict specific HTTP methods and paths?

Configure L7 HTTP policy in a CiliumNetworkPolicy by adding an http rules list inside the egress toPorts rules. A policy that allows GET requests to /api/v1/* but blocks POST, PUT, and DELETE to a specific service specifies toPorts with port 443 and protocol TCP, then adds rules: [{http: [{method: GET, path: /api/v1/.*}]}]. The http method field accepts GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS; the path field accepts Go regex syntax. This policy allows the matched pods to send only GET requests to paths under /api/v1/ on port 443, and Cilium's eBPF enforcement drops any HTTP request that does not match the allowed method and path combination, even though the TCP connection to port 443 is allowed. L7 HTTP policy requires TLS inspection for HTTPS traffic or should be applied to plaintext HTTP connections between pods using mutual TLS handled separately.

How do I use DNS-based egress policy (toFQDNs) to allow traffic to external APIs?

Configure DNS-based egress policy using the toFQDNs rule type in CiliumNetworkPolicy to allow egress traffic to specific domain names rather than IP addresses. A policy allowing egress to api.stripe.com on port 443 defines egress: [{toFQDNs: [{matchName: api.stripe.com}], toPorts: [{ports: [{port: 443, protocol: TCP}]}]}]. Cilium intercepts DNS responses from pods matching the endpointSelector and dynamically updates its eBPF policy maps with the resolved IP addresses of the allowed FQDNs, so the policy stays accurate when cloud provider IP ranges change. Add a DNS proxy rule that allows UDP port 53 to the cluster's DNS service (kube-dns or CoreDNS) before applying toFQDNs policy, since Cilium's DNS interception requires the pod's DNS queries to reach the DNS proxy. Use matchPattern: *.amazonaws.com to allow all AWS service endpoints rather than listing individual service names.

How do I implement a default-deny network policy baseline with Cilium?

Implement a cluster-wide default-deny baseline using CiliumClusterwideNetworkPolicy, which applies to all pods in the cluster rather than a specific namespace. Create a policy with name: default-deny-all that selects all endpoints with an empty endpointSelector (which matches all pods) and defines empty ingress and egress rules (which means deny all). Apply this policy before adding explicit allow policies for each workload. The correct sequencing is: first deploy the default-deny CiliumClusterwideNetworkPolicy, then deploy application-specific CiliumNetworkPolicy resources that allow only required traffic for each service. To avoid breaking the cluster during rollout, deploy Cilium in audit mode first (cilium config set policy-audit-mode=true) which logs policy violations without enforcing them, observe the Hubble flow logs to identify what traffic each workload needs, write allow policies based on observed flows, then switch to enforce mode after the allow policies are in place.

How do I use Hubble to observe network flows and debug policy issues?

Use Hubble CLI to observe real-time network flows from pods to debug policy issues and identify what traffic is being dropped. Install the Hubble CLI and port-forward to the Hubble relay: kubectl port-forward -n kube-system svc/hubble-relay 4245:80. Observe all traffic from a specific pod with hubble observe --pod api/my-api-pod --follow which streams L3/L4 and L7 flow data including source and destination identity, port, HTTP method and path for HTTP flows, and verdict (FORWARDED or DROPPED). To see only dropped flows (policy violations), add --verdict DROPPED to quickly identify what traffic the policy is blocking. For debugging a specific policy interaction, observe flows between two specific pods: hubble observe --from-pod namespace/pod-a --to-pod namespace/pod-b which shows the policy verdict and the specific policy rule that made the forwarding or dropping decision. Hubble UI (accessible via kubectl port-forward svc/hubble-ui 12000:80) provides a graphical service map showing traffic flows between all services in the cluster.

How do I install Cilium and migrate from an existing CNI plugin?

Install Cilium on an existing Kubernetes cluster by first removing the existing CNI plugin and replacing it with Cilium. For EKS clusters, start with helm install cilium cilium/cilium --version 1.15.5 --namespace kube-system --set eni.enabled=true --set ipam.mode=eni --set egressMasqueradeInterfaces=eth0 for AWS ENI-based networking. For GKE, use the GKE dataplane V2 option which uses Cilium under the hood, or install Cilium in a GKE cluster with kube-proxy replacement enabled. The critical constraint for migrating from an existing CNI (Flannel, Calico) is that network connectivity is interrupted during the CNI replacement. Plan the migration as a node-by-node rolling operation: cordon and drain a node, remove the existing CNI pod, install Cilium on the node, verify connectivity, then move to the next node. For production environments, provision new nodes with Cilium from the start rather than migrating existing nodes to avoid the connectivity interruption.

How does Cilium's eBPF-based enforcement differ from iptables-based NetworkPolicy?

Cilium's eBPF-based enforcement provides three advantages over the iptables implementation used by most CNI plugins. First, performance: eBPF programs run in the kernel at packet processing time without the O(n) rule traversal cost of iptables, so adding 10,000 policy rules causes negligible latency increase while iptables performance degrades proportionally with rule count. Second, L7 visibility: eBPF can inspect packet payloads to enforce HTTP method, path, and header policies, while iptables can only match on L3/L4 headers (IP, port, protocol). Third, observability: Cilium's eBPF programs emit flow events for every packet forwarded or dropped, which Hubble collects and exposes as queryable telemetry, while iptables-based implementations require separate tools like network tap or service mesh sidecars to achieve equivalent observability. The main adoption barrier is operational complexity: Cilium requires a compatible Linux kernel (4.9+ for basic operation, 5.3+ for full feature support) and adds a new layer of tooling (hubble CLI, cilium CLI, Cilium Helm chart) that the operations team needs to understand.

Sources & references

  1. Cilium Network Policy Documentation
  2. Cilium L7 HTTP Policy
  3. Hubble Network Observability
  4. Cilium DNS-Based Policies

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.