AI Tools Compared

Kubernetes NetworkPolicies are notoriously tricky to write correctly. A single misconfigured policy can lock down your entire cluster or leave critical security gaps. The YAML syntax is verbose, the logic is counter-intuitive (deny-all-then-allow-needed is safer than allow-all-then-deny-bad), and the interaction between multiple policies compounds the complexity. AI tools can help draft policies quickly, but they often generate permissive defaults that weaken security. This comparison shows how Claude, GPT-4, and GitHub Copilot handle NetworkPolicy generation, including real-world policy examples.

Table of Contents

Understanding Kubernetes NetworkPolicy Fundamentals

Before evaluating AI tools, understand what NetworkPolicies actually do. This is crucial because AI-generated policies often make incorrect assumptions.

A NetworkPolicy is a Kubernetes resource that controls ingress and egress traffic for pods. It works like a firewall rule: specify source/destination IP, protocol, and port. Pods are selected using label selectors. If no policies select a pod, the pod accepts all traffic (default allow). If any policy selects a pod, only traffic matching the policy rules is allowed (default deny within selection).

This default-deny-within-selection behavior confuses many developers. A common mistake: writing policies that are too permissive because the developer didn’t realize that once ANY policy matches a pod, all unspecified traffic is denied.

NetworkPolicies require a network plugin that implements them. Kubernetes has several options:

Calico: Open-source, supports both standard NetworkPolicy and extended Calico-specific policies. Works well in most environments.

Cilium: eBPF-based, provides both NetworkPolicy support and advanced features like application-layer policies and encryption.

Weave: Includes both networking and policies, good for hybrid cloud.

Flannel: Network-only, does not support NetworkPolicies directly.

A critical reality: not all NetworkPlugins implement the full spec. Some have limitations on selectors, cross-namespace rules, or CIDR matching. AI tools sometimes generate policies that work on Cilium but fail on Calico, or vice versa.

Evaluating Claude for NetworkPolicy Generation

Claude excels at explaining NetworkPolicy logic and generating well-reasoned policies with clear intent comments. When asked to generate a policy for a typical microservices architecture (frontend, API, database), Claude produced:

# NetworkPolicy: Allow frontend to API, API to database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
 name: database-ingress
 namespace: production
spec:
 podSelector:
 matchLabels:
 app: database
 policyTypes:
 - Ingress
 ingress:
 - from:
 - podSelector:
 matchLabels:
 app: api
 ports:
 - protocol: TCP
 port: 5432

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
 name: deny-all-egress
 namespace: production
spec:
 podSelector: {}
 policyTypes:
 - Egress
 egress:
 - to:
 - podSelector:
 matchLabels:
 app: any
 ports:
 - protocol: TCP
 port: 53 # DNS
 - to:
 - namespaceSelector:
 matchLabels:
 name: production
 ports:
 - protocol: TCP
 port: 443

Claude’s output demonstrates understanding of the deny-by-default model. The policies explicitly allow only what’s needed. Claude also included comments explaining the logic and mentioned the importance of DNS egress (port 53) which many developers forget.

When asked about differences between Calico and Cilium, Claude explained that Cilium supports layer 7 (application-layer) policies while standard NetworkPolicy is layer 3/4. It suggested using Cilium if you need fine-grained control based on HTTP method or path, but acknowledged that standard NetworkPolicy works everywhere.

Claude’s generated a Cilium-specific policy example:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
 name: api-http-policy
 namespace: production
spec:
 endpointSelector:
 matchLabels:
 app: api
 ingress:
 - fromEndpoints:
 - matchLabels:
 app: frontend
 toPorts:
 - ports:
 - port: "8080"
 protocol: TCP
 rules:
 http:
 - method: "GET"
 path: "/health"
 - method: "POST"
 path: "/api/.*"

Claude correctly noted that this Cilium policy restricts traffic at the HTTP level, not just TCP. It works on specific paths and methods, while standard NetworkPolicy can only restrict by port.

Evaluating GPT-4 for NetworkPolicy Generation

GPT-4 generates complete, syntactically correct policies but tends toward overly permissive defaults. When asked the same microservices question, GPT-4 produced:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
 name: microservices-network-policy
 namespace: production
 labels:
 app: microservices
spec:
 podSelector:
 matchLabels:
 tier: application
 policyTypes:
 - Ingress
 - Egress
 ingress:
 - from:
 - podSelector:
 matchLabels:
 tier: frontend
 ports:
 - protocol: TCP
 port: 8080
 - from:
 - namespaceSelector: {}
 ports:
 - protocol: TCP
 port: 8080
 egress:
 - to:
 - podSelector:
 matchLabels:
 tier: database
 ports:
 - protocol: TCP
 port: 5432
 - to: []
 ports:
 - protocol: TCP
 port: 53
 - protocol: UDP
 port: 53

GPT-4’s policy is functional but has a critical issue: the from rule with empty namespaceSelector: {} allows traffic from ANY namespace. This is overly permissive and violates the principle of least privilege. The developer using this policy without review would weaken cluster security.

When asked to make the policy more restrictive, GPT-4 quickly corrected this and added proper namespace labels. It also suggested adding network policies for DNS, which is good practice. However, the initial generation leaned toward permissiveness, which is dangerous in security contexts.

GPT-4 generated a comparison table without prompting, which was helpful:

| Policy Type | Source | Protocol | Port | CIDR |
|-------------|--------|----------|------|------|
| Ingress | Frontend pods | TCP | 8080 | N/A |
| Ingress | Internal DNS | UDP | 53 | 10.0.0.0/8 |
| Egress | Database pods | TCP | 5432 | N/A |

This table helped clarify what the policies allow. GPT-4’s strength is generating policies with supporting explanations, though you need to review for over-permissiveness.

Evaluating GitHub Copilot for NetworkPolicy Generation

Copilot struggles with NetworkPolicy generation because it lacks context. When given a comment like:

# NetworkPolicy to allow traffic from frontend to API

Copilot auto-completed:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
 name: frontend-api
spec:
 podSelector:
 matchLabels:
 app: api
 policyTypes:
 - Ingress
 ingress:
 - from:
 - podSelector:
 matchLabels:
 app: frontend
 ports:
 - protocol: TCP
 port: 8080

This is correct syntax and logic, but it’s incomplete. There’s no egress policy, no DNS handling, and no deny-all baseline. Copilot generated the minimum viable policy that matches the comment but missed critical security considerations.

When given more context (a partial YAML file with multiple policies started), Copilot improved. It completed policies and sometimes correctly added DNS egress rules:

# Allow all pods to query DNS
- to:
 - namespaceSelector:
 matchLabels:
 name: kube-system
 ports:
 - protocol: UDP
 port: 53

Copilot’s issue: it works line-by-line without understanding the full policy intent. If you provide detailed YAML structure, it fills in correctly. Without structure, it generates incomplete policies.

Real-World Policy Examples: The Three Tools Compared

Let’s walk through a realistic scenario: “Generate NetworkPolicies for a three-tier app (frontend, API, database) in production namespace. Assume Calico is installed. Database should only accept from API, API should only accept from frontend and internal monitoring, frontend accepts from anywhere on port 80/443, all pods can query DNS.”

Claude’s Approach:

Claude generated five separate policies:

  1. Deny-all baseline (empty podSelector, empty ingress/egress)
  2. Frontend ingress (allow external traffic on 80/443)
  3. Frontend egress (allow API and DNS)
  4. API ingress (allow frontend and monitoring namespace)
  5. API egress (allow database and DNS)
  6. Database ingress (allow API only)
  7. Database egress (deny all, no egress needed for read-only database)

The policies were layered and explicit. Claude also included a note: “Start with deny-all, then add explicit allow rules. This is safer because policy logic is AND/OR based—be careful when combining policies.”

GPT-4’s Approach:

GPT-4 generated three policies (frontend, api, database) with both ingress and egress. It included proper namespace selectors and was careful to specify exactly what traffic is allowed. However, it suggested using a separate “monitoring” namespace and provided Prometheus-specific port 9090 rules without being asked. This was thoughtful but added complexity.

Copilot’s Approach:

Copilot generated correct syntax for two policies when given the YAML structure started, then got stuck on the third. It required developer guidance to complete the policies. Once the structure was clear, Copilot filled in selectors and ports correctly.

Aspect Claude GPT-4 Copilot
Completeness Full layered approach Complete single policies Incomplete, needs structure
Security Secure-by-default (deny-all) Good but over-features Correct but minimal
Explainability Excellent reasoning Good with caveats No explanation
DNS Handling Always included Often included Requires prompting
Namespace Handling Explicit and correct Correct but verbose Limited understanding
Calico/Cilium Clarity Distinguishes well Good comparison Not addressed

Common Mistakes in AI-Generated NetworkPolicies

Mistake 1: Missing DNS Egress

All three tools sometimes forget that pods need egress for DNS queries (port 53). Without this, pods can’t resolve service names.

Claude: Usually includes it after asking. GPT-4: Often includes it proactively. Copilot: Misses it unless the developer hints.

Mistake 2: Overly Permissive Namespace Selectors

Using namespaceSelector: {} (empty) means “allow from any namespace,” which is dangerous in shared clusters.

Claude: Explicitly avoids this. GPT-4: Generates this on first pass, corrects on request. Copilot: Generates this without understanding the risk.

Mistake 3: Forgetting Egress Policies

Many examples focus on ingress (traffic into pods) and forget egress (traffic out). This is a significant security gap.

Claude: Always generates both. GPT-4: Generates both, usually correctly. Copilot: Often generates only ingress; egress requires prompting.

Mistake 4: Cross-Namespace Traffic Mistakes

If your app spans multiple namespaces, policies get complex. Selecting pods across namespaces requires both podSelector and namespaceSelector.

Claude: Gets this right consistently. GPT-4: Gets this right but can be verbose. Copilot: Struggles without detailed guidance.

Advanced Scenarios: When AI-Generated Policies Break

Scenario 1: Cilium Layer 7 Policies

All three tools can generate standard NetworkPolicy. Only Claude and GPT-4 generate Cilium-specific layer 7 policies, and both require explicit prompting. Copilot rarely attempts these.

Scenario 2: Network Policies with CIDR Blocks

Restrict traffic from specific IP ranges (CIDR). This is useful for allowing traffic from external systems.

ingress:
 - from:
 - ipBlock:
 cidr: 203.0.113.0/24
 except:
 - 203.0.113.5/32 # Exclude a specific IP
 ports:
 - protocol: TCP
 port: 443

Claude: Generates this correctly and explains the except clause. GPT-4: Generates this with clear examples. Copilot: Requires scaffolding to complete; struggles with the except field.

Scenario 3: Policies for StatefulSets with Headless Services

StatefulSets use headless services for pod-to-pod communication. Policies must allow traffic between specific pod ordinals.

All three tools struggle with this because it requires understanding StatefulSet-specific label patterns.

Scenario 4: Policies with Multiple Namespaces and Cross-Cluster Communication

Production systems often span multiple clusters or namespaces. Policies need to reference external services by CIDR.

Claude: Provides clear guidance on how to structure this. GPT-4: Generates working policies with some caveats. Copilot: Limited understanding; requires significant developer guidance.

Validation: How to Review AI-Generated Policies

After generating policies with AI, always validate them:

  1. Check selector matching: Do the pod selectors actually match your pods? Deploy in dev/staging first and verify with kubectl get pods --selector=app=api.

  2. Verify DNS works: After applying policies, try resolving service names from within a pod. nslookup kubernetes.default should work.

  3. Test cross-namespace traffic: If your app spans namespaces, verify traffic flows. Use kubectl debug to run commands inside pods.

  4. Load test: Policies can have subtle performance implications. Verify that legitimate traffic isn’t being incorrectly filtered.

  5. Audit logs: Enable audit logging to see rejected traffic and catch policies that are too restrictive.

  6. Diff against cluster: Use kubectl diff to see the exact changes policies will make before applying.

Practical Recommendations

Use Claude if:

Use GPT-4 if:

Use Copilot if:

Testing NetworkPolicies in a Development Environment

Always test policies before production deployment:

# Create a dev namespace
kubectl create namespace dev

# Apply policies
kubectl apply -f policies.yaml -n dev

# Deploy test pods
kubectl run test-frontend --image=nginx -l app=frontend -n dev
kubectl run test-api --image=nginx -l app=api -n dev

# Test connectivity
kubectl exec -it test-frontend-pod -n dev -- curl http://test-api:8080

# If the curl succeeds, policies allow traffic
# If it times out, policies block traffic

Use this pattern to validate AI-generated policies before applying to production.

Frequently Asked Questions

Are NetworkPolicies enough for security?

NetworkPolicies are one layer of a defense-in-depth approach. They control network-level access, but you also need authentication, authorization (RBAC), pod security policies, and image scanning. Use NetworkPolicies as part of a security strategy.

How do I debug a policy that’s blocking legitimate traffic?

Enable policy logging. Most network plugins support this. Check audit logs to see what traffic is being rejected. Verify your pod selectors match the intended pods using kubectl get pods --selector=key=value.

Can I test policies without applying them to production?

Yes. Create a test namespace, deploy test pods, apply policies there, and verify traffic works as expected. Use the same policy YAML for production, just apply to different namespaces.

What’s the performance impact of NetworkPolicies?

Minimal for simple policies. Complex policies with many rules or namespace selectors can add latency. Cilium (eBPF-based) is faster than Calico for large numbers of policies. Test in your environment with realistic traffic.

Should I use a service mesh instead of NetworkPolicies?

Service meshes (Istio, Linkerd) provide application-layer traffic management but add complexity. NetworkPolicies are simpler for network-level controls. Many teams use both: NetworkPolicies for pod-to-pod, service mesh for advanced routing.

How do I handle multi-region or multi-cluster traffic?

Use CIDR blocks in NetworkPolicy ipBlock rules. Specify the IP ranges of external clusters. This requires knowing the IP ranges in advance. For dynamic routing across clusters, a service mesh is often better.

Built by theluckystrike — More at zovo.one