Are Kubernetes NetworkPolicies enough? NetworkPolicies are the built-in mechanism in Kubernetes for controlling traffic flow at the IP address or port level, also known as Layer 3 and Layer 4. They allow you to define how Pods communicate with other Pods and Services inside the cluster. For many environments, this works well. But not all CNIs are built the same. As clusters grow and workloads become more diverse, writing and maintaining complex policies can become difficult. Especially when different teams, environments, and identities need to coexist in the same cluster. The standard Kubernetes Network Policies are limited in terms of capability and that’s why many turn to Cilium Network Policies for greater flexibility. This is where Cilium and CiliumNetworkPolicy come in. Cilium fully supports the standard Kubernetes NetworkPolicy, but it also extends it, so you can build more expressive and identity-aware rules that adapt to complex and constantly changing environments. One example is the use of matchExpressions. In standard Kubernetes NetworkPolicy, matchExpressions can only be used within a podSelector or namespaceSelector. Cilium expands both where and how match expressions can be used. Instead of being limited to simple label selection, Cilium allows match expressions to operate on workload identity, and also includes the ability to use logical operators. Cilium network policy language supports the following: In - The label’s value must match one of the specified values. NotIn - The label’s value must not match any of the specified values. Exists - The endpoint must include a label with the specified key. The value is not required. DoesNotExist - The endpoint must not include a label with the specified key. The values field must not be specified This enables richer matching logic. For example, you can write policies such as: “Allow traffic from everything except dev workloads.” So what does this look like in practice? Let’s walk through a few real scenarios Dynamic Workload Selection In microservices environments, workloads are constantly changing. Teams promote applications from dev to staging to prod by updating labels. Pods are deleted and created as versions shift and names change. More often than not, labels are the only stable signal of intent. In traditional networking, security uses the IP as a firewall identifier; which doesn’t scale in the dynamic environment like Kubernetes. This is where matchExpressions become especially powerful in Cilium. With a CiliumNetworkPolicy, you can combine Layer 7 rules with dynamic workload selection. Instead of hardcoding policies to specific Pods or namespaces, you can target identities using expressions For instance, the following policy sets it up to where any frontend app that isn't deprecated can send POST requests to the /api/v2/ endpoint on the payment service (port 8080), but only if that payment service has an environment label set, and no other traffic is allowed out: For this example, we created a high-level diagram of this policy: As labels change, the policy adapts automatically. The rule stays the same, but the workloads it applies to evolve with the cluster. Standard Kubernetes NetworkPolicy cannot enforce HTTP method or path restrictions since it operates only at Layer 3 and Layer 4. This means allowing all HTTP traffic on a given port, such as 8080, which can introduce unnecessary exposure. It also cannot dynamically filter access based on API versions or methods as workload labels change, limiting how precisely you can express intent in fast moving environments. Service Aware Selection In many environments, you do not just want to allow traffic to Pods. You want to allow traffic to Services that meet specific criteria. For example, all production databases that are not read replicas since applications shouldn’t make writes/updates to a read replica. With CiliumNetworkPolicy, you can use toServices together with matchExpressions to dynamically select Services based on their labels. In this example, the policy targets MySQL and Postgres databases in production, while explicitly excluding read replicas and backup roles. This is a significant difference from standard Kubernetes NetworkPolicy which cannot select Services directly using match expressions. You would need to approximate the behavior with pod selectors or manually maintain rules as backend Pods scale or change. Cilium shifts that responsibility to the Service abstraction layer. This way, the policy selects the Service by intent, and Cilium handles endpoint discovery without manual endpoint management. DNS Egress with Conditionals Sometimes the requirement is not just internal segmentation, but controlled access to external resources such as APIs. For example, only certain application tiers should be allowed to reach specific third party endpoints, and only in certain environments. You can conditionally select workloads based on labels that identify these requirements as conditionals. Those identity conditions can then be combined with DNS aware egress rules using toFQDNs. In this example, only workloads that explicitly require external access, meet a defined security level, and are not in a development environment are allowed to resolve DNS and connect to approved external domains. Here we’ve used a combination of matching labels, expressions, and regex patterns to demonstrate how granular CiliumNetworkPolices can be! Standard Kubernetes NetworkPolicy cannot provide FQDN based egress control. You would need to manage external IP CIDR ranges manually, which often change. It also cannot combine DNS based controls with label driven conditional selection, making it impossible to express policies such as: “only high security production workloads may call this external API.” This is where identity-aware matching and DNS enforcement come together in a way that native policies simply cannot express. Summary Kubernetes NetworkPolicy provides a solid foundation for controlling traffic at Layer 3 and Layer 4, but modern platforms often require more expressive controls. As workloads scale, shift environments, and organizations adopt microservices patterns, signal of intent becomes the cornerstone on which to build your policies around. CiliumNetworkPolicy builds on that idea by extending matchExpressions beyond simple pod and namespace selection and tying identity directly to enforcement, including Layer 7 rules, service aware selection, and DNS based egress controls. The result is policy that stays stable even as the cluster changes. Instead of rewriting rules every time Pods scale, labels shift, or services evolve, you define intent once and let identity drive enforcement. For teams operating dynamic, multi environment Kubernetes clusters, that additional flexibility can significantly reduce complexity while improving security precision. Want to learn more about Kubernetes and Cilium NetworkPolicies? Learn how to secure Kubernetes workloads with "Kubernetes Network Policies Done the Right Way." This practical guide covers Zero Trust, effective network policy design, and tools like Cilium and Hubble to help you protect and optimize your infrastructure.