Skip to main content
In this tutorial, we’ll secure a sample application using Cilium Network Policies. We’ll progress from a default Kubernetes NetworkPolicy (Layer 3) to a full L7 HTTP policy with header-based access control. Table of Contents
  1. Demo App Overview
  2. Default Kubernetes NetworkPolicy
  3. Cilium Layer 3 Policy
  4. Cilium Layer 4 Policy
  5. Cilium Layer 7 HTTP Policy
  6. Adding an API Key Header
  7. Further Reading

Demo App Overview

Our demo application runs as a single Pod with two containers listening on ports 5000 and 80. It exposes two corresponding ClusterIP Services.
Both containers serve the same Flask app. We’ll lock down access so only Pods labeled app=admin can communicate.

1. Default Kubernetes NetworkPolicy

We begin with a basic Kubernetes NetworkPolicy named demo-netpol. It selects Pods labeled app=demo and allows ingress from Pods labeled app=admin on all ports.

Verifying the Default Policy

  1. Allowed: Pod with app=admin can reach both ports.
  2. Denied: Pod without the label is blocked.
Before applying Cilium policies, delete the existing Kubernetes NetworkPolicy so that Cilium’s default behavior (allow all) is restored.

2. Cilium Layer 3 Policy

Create cilium-l3.yaml to reimplement the same L3 selector using Cilium’s CRD:
Apply and test:

3. Cilium Layer 4 Policy

Tighten access to only TCP port 80. Update to cilium-l4.yaml:

4. Cilium Layer 7 HTTP Policy

Leverage Cilium’s L7 HTTP inspection to allow only GET /healthz and GET /api. Define cilium-l7.yaml:

5. Adding an API Key Header

Finally, require an X-API-KEY header for the /api endpoint. Update to cilium-l7-header.yaml:

Policy Progression


Further Reading

With Cilium Network Policies, you have full L3–L7 control to secure your workloads. Experiment with custom rules to fit your security requirements!

Watch Video

Practice Lab