Cilium 1.20, the second major open source Cilium release of 2026 after Cilium 1.19, is finally here. Three themes stand out in this release: Gateway API becomes a much broader traffic management layer. Cilium jumps from Gateway API v1.4 to v1.6 and adds ExternalAuth, CORS filters, ListenerSets, and TCPRoute and UDPRoute for non-HTTP traffic. Platform and security teams can manage more of their north-south traffic through the same API, with authentication and authorization handled before a request reaches the application. If you are still running Ingress NGINX, now is the time to let the CNI you already run take on that traffic management too. Cilium becomes a platform that cloud providers can extend. Cilium is already a common networking foundation across hyperscalers and neoclouds. Datapath plugins, developed by Google, make Cilium less like a sealed networking appliance and more like a network operating system: a stable core that cloud providers can extend with their own eBPF programs, independently of the Cilium release cycle. Innovation and standardization move forward together. Cilium continues to push the datapath with innovations such as netkit, while aligning more closely with the wider Kubernetes ecosystem through stable MCS API support and Kubernetes ClusterNetworkPolicy. As capabilities Cilium supported early, including multi-cluster services and cluster-wide policy, take shape as upstream Kubernetes APIs, Cilium supports those APIs alongside its own established CRDs. Users get a choice between Cilium-native features and portable Kubernetes resources. Thank you to every contributor, reviewer and maintainer who made Cilium 1.20 possible, including engineers from Datadog, Google, Microsoft and many other organisations across the Cilium community. Highlights at a glance Cilium 1.20 includes improvements across networking, Gateway API, security, operations and observability. Use the links below to jump to the sections that matter most to you. Networking ENI IPAM with IPv6: Allocate IPv6 prefixes to pods through AWS ENI IPAM. (more details) Automatic netkit selection: Use netkit automatically on supported kernels and fall back to veth on the rest of a mixed fleet. (more details) Datapath plugins: Extend or instrument Cilium's eBPF datapath with independently versioned third-party plugins, without maintaining a fork. (more details) Per-pod source IP verification control: Disable source IP verification for selected pods through an annotation, with a namespace-level opt-in. (more details) Cluster-pool to multi-pool IPAM migration: Move an existing cluster to multi-pool IPAM without rebuilding it. (more details) Topology-aware traffic distribution: Honour Kubernetes PreferSameZone and PreferSameNode hints in Cilium's service load balancer. (more details) EndpointSlice weights for Maglev backends: You can set backends of a Service a larger share of Maglev traffic than others. (more details) Gateway API ExternalAuth: Authenticate and authorize HTTPRoute requests through an external service before they reach the application. (more details) TCPRoute and UDPRoute: Manage databases, DNS, game servers and other non-HTTP services through the same Gateway API model as HTTP and gRPC. (more details) ListenerSets: Let application teams attach their own listeners to a shared Gateway while the platform team retains ownership of the Gateway itself. (more details) More HTTP traffic controls: Configure CORS, additional redirect status codes and the HTTP Server response header natively. (more details) Security ztunnel sidecarless mTLS: Encrypt enrolled pod-to-pod connections through an inline HBONE tunnel, including traffic between pods on the same node. (more details) Kubernetes ClusterNetworkPolicy: Apply upstream, cluster-scoped Admin and Baseline policy tiers alongside namespaced Kubernetes NetworkPolicy. (more details) ClusterMesh policy entity: Select every endpoint across a mesh with the new cluster-mesh entity while consuming fewer policy-map entries. (more details) Policy correlation for audit: Correlate audit verdicts with the responsible policy for analysis. (more details) Day 2 Operations and Scale Stable MCS API support: Use the Kubernetes Multi-Cluster Services API for portable cross-cluster service discovery through ClusterMesh. (more details) Smaller CNI binary: Reduce the cilium-cni binary from roughly 77 MB to 16 MB, shrinking both the image and per-node footprint. (more details) Policy identity aggregation: Represent remote-node and world with semantic wildcard identities, reducing BPF policy-map pressure at scale. (more details) BGP tooling: Inspect route policies, choose clearer peer output formats and use the GoBGP v4-based control plane. (more details) Networking ENI IPAM mode with IPv6 One of the final gaps that stopped us from claiming feature parity across IPv4 and IPv6 in Cilium is gone. It even makes a footnote in Chapter 4 of Cilium: Up and Running redundant, and while we are a little sad that a note in the book is obsolete so soon after publication, we are glad that ENI mode on AWS finally supports IPv6, four years after the feature request was first raised. Let's recap. Up until now, running Cilium in AWS ENI IPAM mode (the AWS-specific mode that gives pods real VPC addresses) was only possible on IPv4. Now, as a beta feature in Cilium 1.20, ENI IPAM can allocate and hand out IPv6 as well. The operator attaches an IPv6 /80 prefix to each node's ENI through Prefix Delegation (which we covered in detail in an earlier blog on how to overcome IP address exhaustion in Kubernetes), and the agent assigns pod addresses from it. Enable ENI IPAM and IPv6 together: Pods on EKS then boot up dual-stack with VPC-routable IPv6: And here is the other side of it in the AWS console: the /80 IPv6 prefix delegated to a worker node's ENI. The IPv6 address from the first pod above comes straight out of this 2a05:d01c:38d:4c02:909e::/80 range. Kudos to the folks at Datadog, one of the most impactful organizations contributing to Cilium for years now, for building ENI IPv6 support and finally closing that gap. Watch the video for a short demo: If you'd like to learn more about this feature, check the documentation for more information. Automatic datapath mode selection (netkit auto) In our post covering netkit, we described the newer pod network device as "The Final Frontier in Container Networking Performance". You can call us out on the hyperbole, but since its release, Meta has rolled it out across millions of containers, while ByteDance has been deploying at a similar scale, reporting a 10% performance improvement in its tests. The TL;DR on netkit is this: it replaces the traditional veth pair and its overhead, bringing pod networking performance to host-level throughput. When it was initially released in Cilium, it needed a recent kernel (>= 6.8), so on a fleet with mixed kernel versions you either gave up on netkit everywhere or carved your nodes into pools by kernel version and configured them separately. Cilium 1.20 adds bpf.datapathMode=auto: each agent probes its own host at startup, uses netkit when the kernel supports it, and quietly falls back to veth when it does not. That means you only need to configure one setting across a mixed fleet, making netkit easier to adopt across your environment. You can see which mode each node actually landed on through cilium-dbg status and the cilium_feature_datapath_config metric: While the default stays veth (meaning nothing changes until you opt in), we feel that the days of veth are numbered. Check the documentation for more info. Datapath Plugins Previously, extending or instrumenting Cilium's eBPF datapath beyond what the project already supported left you with two hard options: upstream your change, or maintain a fork. Both are high-effort, and a fork means carrying datapath patches across every Cilium upgrade. While most end-users just use the off-the-shelf Cilium, some cloud providers - like Google, the authors of this new feature - would manage their own Cilium fork, with the maintenance efforts it comes up with. Now, Cilium 1.20 introduces datapath plugins (beta): third-party code can instrument Cilium's eBPF datapath as its own plugin, running as a separate process that Cilium reaches out to, without patching or forking Cilium itself. Because a plugin is its own image, it is built, versioned and rolled out on its own cadence and can be upgraded independently of Cilium. And because it runs on its own, a plugin crash does not take the agent down with it. It opens the door to specialised observability, security and networking extensions that ship and evolve independently of the Cilium release cycle, with no fork required. A plugin registers itself with Cilium through a deliberately small CiliumDatapathPlugin custom resource: Thanks to jrife for the feature. If you'd like to learn more about this feature, check the documentation for more information or watch the short terminal recording below: Per-pod disable source IP verification By default, Cilium enforces source IP verification: a pod may only send packets whose source IP matches its own. This stops a compromised or misbehaving pod from spoofing another workload's address. There are - admittedly rare - circumstances where some workloads legitimately need to emit packets with a different source IP: for example, NAT gateways, firewalls and other appliance-style pods (such as VPN/Tailscale) . Until now, source IP verification was a single cluster-wide switch (enable-source-ip-verification, on by default) with no per-pod control - so letting one workload use a foreign source IP meant turning it off for the entire cluster, weakening anti-spoofing everywhere. Cilium 1.20 makes it a per-pod, opt-in decision, gated at two levels. First, a cluster administrator permits it for a namespace by annotating the namespace with config.cilium.io/delegate-source-ip-verification: "true". Only then can a pod owner opt a specific workload out of source IP verification by annotating it with config.cilium.io/disable-source-ip-verification: "true". Both annotations are required, so a namespace owner cannot quietly turn anti-spoofing off on their own, and the protection stays on everywhere else. This feature solves a problem for the workloads that need it, but make sure to use Kubernetes RBAC to restrict who can modify namespace annotations, so you don't accidentally reduce your security posture. If you'd like to learn more about this feature, check the documentation for more information. Migrate cluster-pool IPAM to multi-pool IPAM Multi-pool IPAM is steadily becoming the preferred way to hand out pod IPs in Cilium. Instead of drawing every address from one flat cluster-wide range, you carve the space into named pools and assign them where you want them - per namespace, per workload, per tenant. What had been difficult until now was the migration from the default cluster scope mode. Until now, if your cluster was already running cluster-scope IPAM, moving to multi-pool meant standing up a fresh cluster and migrating workloads across, which is not something anyone wants to do on a live platform. Cilium 1.20 adds an in-place migration path. You can switch an existing cluster from cluster-pool to multi-pool, with no rebuild and no re-IP'ing, by using the operator option enable-cluster-pool-to-multi-pool-migration. Here is what a migration looks like in practical terms: Check out the migration documentation for more info. Traffic distribution PreferSameZone / PreferSameNode Introduced in Cilium 1.16, Service Traffic Distribution became the preferred method for keeping Service traffic close to its client, replacing the older topology-aware hints method. Service Traffic Distribution enables users to reduce latency and avoid cross-zone data-transfer charges, as Dean covered in this excellent post. Until now, Cilium only supported the PreferClose value, indicating a preference for routing traffic to endpoints that are topologically proximate to the client. In Cilium 1.20, Cilium honours recent changes to the upstream Kubernetes trafficDistribution specification and now supports two newer values. PreferSameZone keeps traffic within the client's zone while a healthy backend is available there, and PreferSameNode prefers a backend on the very same node. Both values gracefully fall back to the rest of the cluster's backends when no local one is healthy, so you get the locality benefit without trading away availability. Because this is the standard Kubernetes field rather than a Cilium-specific annotation, the same Service spec behaves consistently across conformant implementations. Check the official Kubernetes documentation for more information on service traffic distribution. EndpointSlice weights for Maglev backends Cilium has supported Maglev as its load balancer hashing mechanism since Cilium 1.10. Originated at Google and named after the Japanese magnetic levitation train, Maglev provides consistent hashing to minimize disruption during node or backend changes (you can find more information about Maglev and other performance optimization features in Chapter 8 of Cilium Up and Running). In prior releases, there was no supported way to give some backends of a Service a larger share of Maglev traffic than others, or to gracefully drain a group of backends. Traffic was evenly distributed across all available backends. Now, Cilium 1.20 reads a service.cilium.io/weight annotation directly off the EndpointSlice. The weight applies to every backend in that slice, with valid values running from 0 to 65535 (note the weights are relative, so they do not need to add up to 100). This is aimed squarely at selectorless Services backed by several manually managed EndpointSlice objects, where each slice can carry a different weight: a classic weighted split such as 70/30 across two slices becomes a two line annotation change. The special case is a weight of 0. Instead of removing the backends, it marks them as being in maintenance: existing connections continue to work, but the backends leave the Maglev lookup table so no new connections are steered to them. That gives you a clean, connection-preserving drain, which is exactly what you want when taking a group of backends out of rotation for maintenance. Invalid values are ignored and fall back to the default behaviour, so a typo never takes a Service down. Watch the demo below to learn more: Gateway API Cilium 1.19 introduced support for Gateway API v1.4. Cilium 1.20 moves from Gateway API v1.4 to v1.6 and implements several of the capabilities that graduated across those releases. From v1.5, TLSRoute (a feature Cilium introduced back in 1.14), the HTTPRoute CORS filter and ListenerSets all reached the Standard channel as generally available, and Gateway (and HTTPRoute) level authentication landed as an experimental feature. From v1.6, TCPRoute and UDPRoute graduated to Standard as well. Gateway API continues to be a thriving project. Its accelerated development is a boon to anyone looking at migrating off Ingress - and its most popular implementation, Ingress NGINX - and Cilium keeps up with its pace. Gateway API ExternalAuth filter Cilium's security features have always stood out. Built-in traffic encryption within or between meshed clusters, network policy for cluster segmentation, mutual TLS (now with zTunnel, which we cover later) provide a compelling set of security capabilities. One gap remained at the north/south boundary: authenticating users, scripts, and agents arriving from outside wasn’t easy to accomplish natively and, in prior releases, required customizing Cilium’s built-in Envoy proxy. Cilium 1.20 closes that gap, by supporting the ExternalAuth filter in Gateway API (GEP-1494). The idea is simple. You attach the filter to an HTTPRoute, and for every matching request the gateway checks with an external authorization service before forwarding any traffic. If the caller hasn't authenticated yet, the authorizer sends them through an authentication flow first - a 302 redirect to a login page for a human in a browser, or a 401 / 403 for a request that presents no valid credentials. Only once the caller has authenticated and the authorizer returns 200 OK does the gateway forward the request to your backend. On the way through, the authorizer can also inject identity headers (who the caller is and which groups they belong to) so your application makes the final authorization call without ever touching a password or a token. The feature applies to very different callers on the same gateway. A human hitting the dashboard in a browser gets redirected to an SSO provider (such as Authelia or Duo) and comes back with a session cookie. A CI job or script presents a JWT that oauth2-proxy validates against an identity provider (such as Keycloak, Duo or Okta). And an AI agent talking MCP authenticates with a service-account client, with no interactive login at all. The filter sits directly on the HTTPRoute: The authorizer's response determines what the gateway does: 200: forward the request to the backend. 302: redirect the caller, for example to an SSO login page. 401 or 403: block the request at the gateway. If you’d like to learn more, check out our External Auth lab! Gateway API TCPRoute and UDPRoute support Ever since Gateway API arrived in the 1.13 release, Cilium has kept in lockstep with every Gateway API release, adding TLS termination, TLS Passthrough, GRPCRoute, GAMMA (for east-west use cases) and many more features along the way. Cilium 1.20 carries on in this vein. On top of the ExternalAuth feature mentioned above, a big addition to Cilium's Gateway API support is TCPRoute and UDPRoute. Prior to this release, to expose a plain TCP or UDP service (a database, a DNS server, a game server) you had to drop out of the Gateway API model and back to raw LoadBalancer or NodePort Services. With TCPRoute and UDPRoute support, you can now manage L4 services through the same Gateway API you already use for HTTP or gRPC. UDPRoute is ideal for applications such as DNS, VoIP, gaming, streaming media, IoT and telemetry (GEP-2645), while TCPRoute is handy for databases, message brokers, mail protocols and other TCP-based services (GEP-2644). You can attach HTTP, TCP and UDP routes to a single shared Gateway: In this example, an HTTPRoute serves Dean's eBee Pac-Man app, a TCPRoute connects to the MongoDB database holding its high scores, and a UDPRoute sends DNS queries to CoreDNS: Each backend is reachable through the same Gateway address (172.18.255.200) on its own port. After playing a round of eBee Pac-Man over the HTTPRoute, the score lands in MongoDB and can be read back over the TCPRoute: CoreDNS is available over the UDPRoute: Thanks to external contributor eminaktas for landing this long-standing request. Gateway API ListenerSets Shared Gateways create an awkward ownership problem: the platform team controls the Gateway object, but application teams own the endpoints behind it. Adding another hostname or port therefore requires someone with write access to modify that central resource, creating a potential bottleneck in multi-tenant clusters. Without a delegation mechanism, this risks reproducing the same centralized configuration problem found in the inflexible Ingress API, one of the limitations Gateway API was designed to address. Cilium 1.20 implements Gateway API ListenerSets, allowing application teams to attach and manage additional Listeners from their own namespaces. These Listeners share the parent Gateway’s address and infrastructure, while the platform team retains ownership of the Gateway and controls which namespaces may extend it. The result is a clean delegation model with per-namespace ownership and correct hostname filtering for attached routes. The following manifests show this delegation in practice: a platform-owned Gateway authorizes a labelled application namespace to add its own Listener, while an HTTPRoute in that namespace attaches directly to the delegated Listener. For more details on ListenerSet, check the documentation for more information. More Gateway API improvements Alongside the move from Gateway API v1.4 to v1.6, Cilium 1.20 fills in several smaller but useful gaps in its HTTP traffic handling. Cilium now supports the Gateway API CORS filter natively. You can declare allowed origins, methods and headers, exposed response headers, credential handling and cache duration directly on the route. Redirect handling is more complete too. In addition to 301 and 302 redirect codes we covered in the deep dive tutorial on “Redirect, Rewrite, and Mirror HTTP with Cilium Gateway API”, Cilium now formally supports and tests the optional 303, 307 and 308 HTTPRoute redirect codes. This gives users more precise control over whether a redirect is temporary or permanent and whether the original HTTP method and body should be preserved. You can try out redirection in the Advanced Gateway API Use Cases lab below: Finally, CiliumGatewayClassConfig can now control the HTTP Server response header. Its OVERWRITE, APPEND_IF_ABSENT and PASS_THROUGH modes let operators replace the header, add one only when the backend has not supplied it, or preserve the backend value. This is useful for applying a consistent value or preventing backend implementation details from being exposed. Security ztunnel: sidecarless mTLS service mesh Cilium 1.19 introduced ztunnel, a purpose-built per-node proxy that brings sidecarless mutual TLS to pod-to-pod traffic, and Cilium 1.20 keeps that work moving. The longer-term direction is for ztunnel to supersede Cilium's original mutual authentication feature, which has been Beta since 1.14. That feature intentionally separated authentication from encryption. Cilium agents performed an out-of-band mTLS handshake to authenticate each new identity pair, while Cilium's existing IPsec or WireGuard transparent encryption protected the workload traffic. This allowed mutual authentication to build on encryption capabilities Cilium already provided. One consequence of this design was that the first packet could be dropped while the authentication handshake completed. In addition, because transparent encryption operates between nodes, traffic between pods on the same node was not encrypted. ztunnel takes a different approach by providing authentication and encryption together in the traffic path. Once you enroll a namespace by applying the io.cilium/mtls-enabled=true label, ztunnel holds each new connection while it establishes an mTLS session using TLS 1.3 over an HBONE (HTTP-Based Overlay Network Environment) tunnel. This avoids the first-packet drop and encrypts every supported TCP flow between enrolled pods, including pods running on the same node. ztunnel remains Beta, but Cilium 1.20 improves its operational readiness. The certificate authority is now configurable: the default internal mode runs ztunnel mTLS without requiring SPIRE, while spire mode uses SPIFFE workload identities, with SPIRE issuing and rotating certificates for teams that want the CNCF-graduated SPIFFE and SPIRE identity stack. There are also new Prometheus metrics for enrollment and connection health. The dashboard below combines those metrics with Kubernetes workload data to show protected workloads, enrollment activity, failures and the connection state of each node's ztunnel. These improvements continue the joint engineering effort between Microsoft and Isovalent and build on the upstream ztunnel project, originally created for Istio's ambient mesh. As ztunnel matures, it is becoming the clear successor to the original mutual authentication feature. In Cilium 1.20, the maintainers marked legacy Mutual Authentication as deprecated, with removal planned for a later release. Ztunnel support in Cilium remains currently in Beta. Make sure to review the documentation for current limitations and configuration guidance before rolling this out in production. For more information, see the native mTLS deep-dive and the ztunnel introduction in the Cilium 1.19 release blog. Kubernetes ClusterNetworkPolicy (KCNP) support A Kubernetes NetworkPolicy (KNP) is namespaced and additive: it is written by application teams, and there is no native way for a cluster administrator to set a rule that applies cluster-wide or that takes precedence over what a namespace owner writes. The upstream network-policy-api subgroup has been working on filling that gap, and its latest iteration consolidates the earlier AdminNetworkPolicy and BaselineAdminNetworkPolicy into a single ClusterNetworkPolicy. Cilium 1.20 implements ClusterNetworkPolicy. It is cluster-scoped and tiered: an Admin tier that takes precedence over namespaced NetworkPolicy, and a Baseline tier that acts as a default which namespaced policy can override. A policy selects a subject (by namespace or pod), sets a priority, and lists ingress/egress rules with an action of Accept, Deny or Pass. Those selectors accept matchExpressions in addition to matchLabels so you can target sets of namespaces or pods with set-based rules like In, NotIn and Exists. This gives platform teams the guardrails they have wanted: enforce a cluster-wide baseline, or hard-deny some traffic that no namespace can re-open. For example, an Admin-tier policy can deny all ingress to a selected namespace: For users who prefer using upstream APIs like KNP and KCNP rather than Cilium-specific Cilium Network Policies and ClusterWide Cilium Network Policies, this is a welcome addition to your segmentation toolkit. If you'd like to learn more about this feature, check the documentation for more information. New cluster-mesh policy entity & policy map aggregation In previous Cilium versions, allowing traffic from "anywhere in my Cluster Mesh" in Cilium Network Policies meant either enumerating remote clusters by name or falling back to label selectors that spanned the mesh, since the cluster entity only covered the local cluster. Such policy was verbose to write, easy to get wrong as clusters came and went, and costly at scale because each remote identity consumed its own BPF policy-map entry. Now, Cilium 1.20 adds a cluster-mesh policy entity that selects every endpoint in every meshed cluster in a single word. You write fromEntities: cluster-mesh once and it keeps matching as clusters join or leave the mesh. Underneath, both cluster and cluster-mesh now aggregate their identities into far fewer policy-map entries, so the mesh-wide rule is also the cheaper one to enforce at scale. The policy is as simple as using the new entity in fromEntities: The diagrams below illustrate the changes: If you'd like to learn more about this feature, check the documentation for more information or watch the terminal recording for a short demo: Hubble policy correlation for audit verdicts Previously, when a flow was dropped by a default-deny (nothing matched it) or logged under Policy Audit Mode, Hubble showed the drop but left the policy fields empty. You could see that a flow was denied, but not which policy, or the absence of one, was responsible. That gap made audit mode harder to trust: the whole point of audit mode is to preview what a policy would block before you enforce it, but the verdict did not tell you what would have caught the flow. Now, in Cilium 1.20, Hubble correlates policy for audit verdicts. Audit flows (Verdict_AUDIT) populate the ingress_allowed_by / egress_allowed_by and ingress_denied_by / egress_denied_by fields, so you can see exactly what would have denied the flow before you flip enforcement on. For example, given this ingress deny policy: When xwing with label alliance tries to curl deathstar, an audited flow now names the policy that would have denied it on ingress: Here is an example of a correlation flow log for a packet allowed on egress, with the corresponding network policy: The terminal recording below takes you through examples of audit policies: Thanks to Rajneesh180 for the contribution. Day 2 Operations & Scale MCS-API reaches stable support in ClusterMesh Cilium Cluster Mesh provides cross-cluster service discovery and load balancing across up to 255 clusters by default, with built-in support for network policy (as highlighted earlier), observability and service affinity. While Cluster Mesh is a popular Cilium feature, it is coupled tightly with Cilium. not portable and vendor-neutral. The Kubernetes SIG multi-cluster working group drove the creation of the portable and vendor-neutral Multi-Cluster Services API standard. Cilium introduced beta MCS-API support a few releases ago and in 1.20, promoted its MCS-API implementation to a stable support level. The MCS-API provides a standard way to make a Service discoverable across multiple clusters. Imagine that an application runs in two clusters called site-a and site-b, behind a Service named web in the default namespace. Normally, each Service is visible only inside its own cluster. To make web available across the mesh, you create a ServiceExport with the same name and namespace in both clusters. That is the only additional resource the application team needs to manage. Cilium then combines the exported Services and their backends into a single multi-cluster Service. Workloads in any connected cluster can reach it through the standard MCS-API DNS name web.default.svc.clusterset.local. Because this naming convention and the ServiceExport resource are part of the Kubernetes MCS-API, the same application manifests can be used with any conformant implementation. Under the hood, the Cilium operator creates the corresponding ServiceImport, allocates the clusterset virtual IP and reconciles the derived Kubernetes Service used to connect to backends across the mesh. Cilium 1.20 moves this implementation to the multicluster.x-k8s.io/v1beta1 CRDs and installs the required CRDs automatically. Of course, Cilium Global Services remain available, but you now also have a stable, supported alternative for cross-cluster service discovery that uses a portable, standard Kubernetes API. Thanks to Arthur Outhenin-Chalandre (@MrFreezeex) from Ledger, who authored both the move to the v1beta1 API and the work to promote Cilium’s MCS-API support to stable. If you'd like to learn more about this feature, check the documentation for more information. Shrink cilium-cni binary by 80% Every Cilium agent ships the cilium-cni plugin and installs it onto the node at /opt/cni/bin/cilium-cni by default, where the kubelet calls it to wire up each pod. Over time what was originally a small binary had grown: the CNI plugin was pulling in large chunks of the agent codebase through Go imports, and by 1.19 it weighed 76 MB. In 1.20, the plugin is no longer importing packages it never needs and the same binary is 16 MB, resulting in a 79% cut. A smaller binary on every node means a smaller image layer to pull and less to copy during each CNI install. remote-node / world policy identity aggregation In previous Cilium versions, a policy that selected a broad entity like world or remote-node expanded, under the hood, into one entry per matching identity in the BPF policy map. On a large or heavily meshed cluster that could mean thousands of entries for a single rule, and in the worst case the policy map could fill up. Now, Cilium 1.20 teaches the policy map a new kind of wildcard for exactly these semantic groups. Selecting world or remote-node now inserts a single aggregated wildcard entry instead of one entry per matching identity, and the datapath does an extra wildcard lookup to match. The verdict is identical, but the footprint collapses from thousands of entries to a handful, so policy enforcement stays cheap as the cluster and the mesh grow. Watch the terminal recordings to compare the behaviour between 1.19… And 1.20: BGP Tooling Improvements Cilium's BGP support is commonly used in self-managed Kubernetes clusters, to interconnect with an existing network fabric. Cilium BGP relies on the GoBGP platform, a robust and mature Go-based implementation of BGP. In previous versions, debugging a Cilium BGP session from the agent was sometimes challenging: the on-agent BGP commands gave limited output, and there was no way to see which route policies were actually being applied to the speaker. Cilium 1.20 improves the on-agent BGP tooling, now surfaced through the hive-shell from inside the Cilium agent (cilium-dbg shell -- bgp/...). A brand-new bgp/route-policies command shows the route policies Cilium has actually programmed into GoBGP - something you previously had no way to inspect. In addition, bgp/peers gains a --format option (table, JSON or detailed); providing a detailed view of per-peer timers, negotiated capabilities and graceful-restart state. Heads-up worth calling out: the on-agent cilium-dbg bgp subcommands and the local REST BGP API are deprecated in 1.20. Move to the hive-shell equivalents - cilium-dbg shell -- bgp/peers, bgp/routes, bgp/route-policies. The user-facing cilium bgp CLI is unchanged. Conclusion Cilium 1.20 is the product of a community that continues to grow well beyond the code itself. Asana, Etraveli, Michelin, OpenAI, Suse, Telefónica's acens, and Zynga have all shared stories about running Cilium in production. If your organization has a story to tell, we would love to hear it. The community also gathered at CiliumCon and the Cilium Developer Summit in Amsterdam, with the CiliumCon talks now available to watch online. The next opportunity to meet in person will be at KubeCon + CloudNativeCon North America in Salt Lake City, where CiliumCon and another Developer Summit will take place from November 9 to 12. We look forward to seeing you there!