Skip to main content
Learn how to generate Kubernetes and Cilium Network Policies from observed runtime traffic.

Overview

Network Policies in Kubernetes are like firewalls for your pods - they control which pods can communicate with each other. kguardian observes actual traffic patterns and generates policies that allow only the connections your application actually uses.
Best Practice: Let your application run under normal load for at least 5-15 minutes before generating policies. This ensures you capture all typical communication patterns.

Basic Usage

Generate for a Single Pod

The simplest use case - generate a policy for one specific pod:
1

kguardian discovers the pod

The CLI queries the broker for all traffic involving my-app in the production namespace
2

Analyzes traffic patterns

  • Identifies all unique source IPs (for ingress rules)
  • Identifies all destination IPs (for egress rules)
  • Resolves IPs to pods/services
  • Groups by port and protocol
3

Generates YAML

Creates production-my-app-standard-networkpolicy.yaml in the ./policies directory
Generated policy example:

Batch Generation

All Pods in a Namespace

Generate policies for every pod in a namespace:
This will create one policy file per pod in the namespace.

All Pods Across All Namespaces

For cluster-wide policy generation:
This can generate hundreds of files in large clusters. Use with caution and review before applying.

Cilium Network Policies

Cilium is an advanced CNI that provides enhanced network policies with L7 (HTTP, gRPC, Kafka) visibility and identity-based rules.

Generate Cilium Policies

Cilium policy example:
Each peer gets a single endpoint selector built from that peer’s labels: the Service’s selector when the IP resolves to a Service (as with kube-dns above), the pod’s labels otherwise. toCIDR/fromCIDR entries appear only for IPs that can’t be resolved to a pod or Service. Label keys in the generated YAML carry Cilium’s k8s: source prefix.

Cilium vs Kubernetes Policies

If you’re running Cilium CNI, use --type cilium for better security and features. Otherwise, stick with --type kubernetes (the default).

Dry Run and Applying

Dry Run (Default)

By default, gen networkpolicy runs in dry-run mode - it saves policies to files without applying them to the cluster:
Applying directly from the CLI is not implemented. Passing --dry-run=false currently behaves the same as dry-run — policies are only saved to files — and the CLI logs a warning to that effect. Apply the generated files with kubectl apply -f.
  1. Generate policies in dry-run mode
  2. Review the generated YAML files
  3. Test in a staging environment
  4. Apply with kubectl after validation:
Use with caution! Applying network policies can break communication if the observed traffic was incomplete. Always test in non-production first.

Advanced Options

Custom Output Directory

Save policies to a specific location:
Skip file creation and just print the policy:
Useful for piping to other tools:

Understanding Generated Policies

Policy Structure

Every generated policy includes:
  1. podSelector: Identifies which pods this policy applies to
  2. policyTypes: Declares whether it has Ingress, Egress, or both
  3. ingress: List of allowed incoming connections
  4. egress: List of allowed outgoing connections

How Peers are Identified

kguardian resolves IPs to Kubernetes resources:
When traffic is between pods, kguardian generates:
This allows traffic from any pod with app=my-service in the production namespace.
For traffic to a Kubernetes Service, kguardian uses the service’s selector:
For traffic to external IPs (e.g., public APIs), kguardian generates CIDR blocks:
kguardian automatically detects DNS queries:

Common Scenarios

Scenario 1: Microservices Application

You have a 3-tier app: frontendbackenddatabase.
Result:
  • frontend policy allows ingress from ingress controller, egress to backend
  • backend policy allows ingress from frontend, egress to database
  • database policy allows ingress from backend only

Scenario 2: Multi-Namespace Communication

Your app in staging talks to a shared database in data:
Generated egress rule includes:

Scenario 3: Default Deny + Allowlist

Start with default-deny, then allowlist only observed traffic:
Now your namespace runs default-deny — only explicitly observed communication is allowed.

Troubleshooting

No Traffic Data

Symptom: CLI says “No traffic data found for pod” Solutions:
  1. Ensure the pod has been running for at least 5 minutes
  2. Generate some traffic (hit HTTP endpoints, trigger background jobs, etc.)
  3. Check broker has data:

Generated Policy Too Permissive

Symptom: Policy allows more than expected (e.g., allows entire namespace) Cause: Pods may lack specific labels, so kguardian falls back to broader selectors. Solution:
  1. Add specific labels to your pods
  2. Manually edit generated policies to tighten selectors
  3. Re-generate after labeling

Policy Breaks Communication

Symptom: After applying policy, some connections fail Cause: Incomplete observation period - not all traffic was captured Solution:
  1. Check pod logs for connection errors
  2. Identify missing ingress/egress rules
  3. Manually add missing rules or extend observation period

Generate Seccomp Profiles

Restrict syscalls based on observed behavior

CLI Reference

Complete flag documentation

Policy Gallery

Worked examples for nginx, Postgres, Prometheus, Istio, and more