Cilium Series Part 15: Introduction to Layer 7 CiliumNetworkPolicy

This article was last updated on: May 17, 2026 am

Series Articles

Introduction

Today we dive into Cilium security topics, introducing the biggest difference between CiliumNetworkPolicies and standard Kubernetes NetworkPolicies: Layer 7 network policy capabilities.

CiliumNetworkPolicy Layer 7 Capabilities

One of the biggest differences between CiliumNetworkPolicy and standard NetworkPolicy is support for L7 protocol-aware rules. In Cilium, you can define protocol-specific L7 policies for various protocols, including HTTP, Kafka, and DNS.

Layer 7 policy rules extend the toPorts section of Layer 4 policies and can be used for both Ingress and Egress.

│ 📝Notes

│ <networkpolicy.io> currently only supports editing and creating L3/L4 policies. You can use the visual editor to create an L4 CiliumNetworkPolicy first, then extend it to an L7 CiliumNetworkPolicy YAML as needed.

Layer 7 policy rule attributes vary depending on the protocol supported by Cilium. Protocol-specific attributes are covered in the detailed documentation. The following sections primarily use HTTP as an example.

L7 HTTP Policy

When any L7 HTTP policy is active for any endpoint running on a node, the Cilium Agent on that node starts an embedded local HTTP agent service (based on Envoy, with the binary cilium-envoy) and instructs the eBPF programs to forward packets to this local HTTP proxy. The HTTP proxy is responsible for interpreting L7 network policy rules and forwarding packets as appropriate. Additionally, once the HTTP proxy is in place, you gain L7 observability in Hubble traffic flows, which we will cover in a later article.

When writing L7 HTTP policies, the HTTP proxy can use several fields to match network traffic:

  • PATH: An extended POSIX regex that matches the regular path of the URL request. If omitted or empty, all paths are allowed.
  • Method: The method of the request, such as GET, POST, PUT, PATCH, DELETE. If omitted or empty, all methods are allowed.
  • Host: An extended POSIX regex that matches the host header of the request. If omitted or empty, all hosts are allowed.
  • Headers: A list of HTTP headers that must be present in the request. If omitted or empty, requests are allowed regardless of whether headers are present.

The following example uses several L7 HTTP protocol rules with regex path definitions to extend an L4 policy, restricting all endpoints with the app=myService label to only receive packets on TCP port 80. When communicating on this port, only the following HTTP API endpoints are allowed:

  • GET /v1/path1: Exact match for “/v1/path1”
  • PUT /v2/path2.*: Matches all paths starting with “/v2/path2”
  • POST .*/path3: Matches all paths ending with “/path3”, with the additional constraint that the HTTP header X-My-Header must be set to true:

The specific policy is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "l7-rule"
spec:
endpointSelector:
matchLabels:
app: myService
ingress:
- toPorts:
- ports:
- port: '80'
protocol: TCP
rules:
http:
- method: GET
path: "/v1/path1"
- method: PUT
path: "/v2/path2.*"
- method: POST
path: ".*/path3"
headers:
- 'X-My-Header: true'

This rule block contains L7 policy logic that extends the L4 Ingress policy. You can start with an L4 policy and provide fine-grained HTTP API support simply by adding the corresponding rule block as an attribute within the toPorts list.

L7 Policy Examples

Let’s look at a few more L7 policy examples:

First, an HTTP L7 policy: Allow entities with env=prod to HTTP GET /public on app=service pods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "Allow HTTP GET /public from env=prod to app=service"
endpointSelector:
matchLabels:
app: service
ingress:
- fromEndpoints:
- matchLabels:
env: prod
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "GET"
path: "/public"

Second, a Kafka L7 policy: Enable the Star Wars Empire Headquarters (app: empire-hq) to produce messages to the empire-announce and deathstar-plans topics.

│ 📝Notes

│ The demo application Cilium uses to showcase CiliumNetworkPolicy capabilities borrows the Star Wars Empire and Rebel Alliance concepts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "enable empire-hq to produce to empire-announce and deathstar-plans"
endpointSelector:
matchLabels:
app: kafka
ingress:
- fromEndpoints:
- matchLabels:
app: empire-hq
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- role: "produce"
topic: "deathstar-plans"
- role: "produce"
topic: "empire-announce"

Third, a DNS L7 policy: “tofqdn-dns-visibility”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: "tofqdn-dns-visibility"
spec:
endpointSelector:
matchLabels:
any:org: alliance
egress:
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchName: "cilium.io"
- matchPattern: "*.cilium.io"
- matchPattern: "*.api.cilium.io"

- toFQDNs:
- matchName: "cilium.io"
- matchName: "sub.cilium.io"
- matchName: "service1.api.cilium.io"
- matchPattern: "special*service.api.cilium.io"
toPorts:
- ports:
- port: "80"
protocol: TCP

In this example, the L7 DNS policy allows queries for cilium.io, any subdomain of cilium.io, and any subdomain of api.cilium.io. No other DNS queries are permitted.

A separate L3 toFQDNs Egress rule allows connections to any IP returned by DNS queries matching cilium.io, sub.cilium.io, service1.api.cilium.io, and special*service.api.cilium.io — for example, special-region1-service.api.cilium.io, but not region1-service.api.cilium.io. DNS queries for anothersub.cilium.io are allowed, but connections to the returned IPs are not, since no L3 toFQDNs rule selects them.

Summary

Today we dove into Cilium security topics, introducing the biggest difference between CiliumNetworkPolicies and standard Kubernetes NetworkPolicies: Layer 7 network policy capabilities.

L7 policies are built as extensions on top of L4 policies by adding the toPorts field. We also provided L7 policy examples for HTTP, DNS, and Kafka.

In upcoming articles, we will walk through a detailed demonstration based on Cilium’s official Star Wars demo.


Cilium Series Part 15: Introduction to Layer 7 CiliumNetworkPolicy
https://e-whisper.com/posts/48332/
Author
east4ming
Posted on
July 27, 2023
Licensed under