Turn real traffic into safe CiliumNetworkPolicies in minutes.
PolicyPilot learns from Hubble flows, proposes least-privilege policies, verifies them safely, and explains results with diagrams.
- 🔍 Learn: Capture and parse Hubble network flows
- 🎯 Propose: Generate least-privilege CiliumNetworkPolicies from observed traffic
- ✅ Verify: Validate policy syntax and structure
- 📊 Explain: Generate HTML reports with network graphs and statistics
- Go 1.23+ installed
- Access to Hubble flows (JSON format) or Hubble CLI
git clone https://github.com/prabhakaran-jm/cilium-policypilot.git
cd cilium-policypilot
go build -o cpp ./cmd/cpp# 1. Learn from Hubble flows
./cpp learn --input examples/sample-flows.json
# 2. Generate policies
./cpp propose
# 3. Verify policies
./cpp verify
# 4. Generate HTML report
./cpp explainCapture or read Hubble flows from JSON files.
# Read from file
./cpp learn --input flows.json
# Specify output location
./cpp learn --input flows.json --output my-flows.jsonFlags:
-i, --input: Input flows JSON file (default:out/flows.json)-o, --output: Output flows JSON file (default:out/flows.json)-d, --duration: Duration to capture flows (future use)--hubble-endpoint: Hubble API endpoint (future use)
Generate CiliumNetworkPolicies from parsed flows.
# Generate policies from default flows file
./cpp propose
# Filter by namespace
./cpp propose --namespace hipstershop
# Custom input/output
./cpp propose --input my-flows.json --output my-policies.yamlFlags:
-i, --input: Input flows JSON file (default:out/flows.json)-o, --output: Output policy YAML file (default:out/policy.yaml)-n, --namespace: Filter flows by namespace (optional)
Validate policy YAML syntax and structure.
# Verify default policy file
./cpp verify
# Verify custom policy file
./cpp verify --input my-policies.yamlFlags:
-i, --input: Input policy YAML file (default:out/policy.yaml)
Validates:
- YAML syntax
- Required fields (apiVersion, kind, metadata, spec)
- CiliumNetworkPolicy structure
- Endpoint selectors
- Ingress/egress rules
- Port and protocol specifications
Generate HTML report with flow statistics, policies, and network visualization.
# Generate report from default files
./cpp explain
# Custom files
./cpp explain --flows my-flows.json --policies my-policies.yaml --output report.htmlFlags:
-f, --flows: Input flows JSON file (default:out/flows.json)-p, --policies: Input policies YAML file (default:out/policy.yaml)-o, --output: Output HTML report file (default:out/report.html)
Report includes:
- Statistics dashboard (flows, policies, namespaces, protocols)
- Interactive Mermaid network graph
- Policy list with endpoint selectors
- Namespace and protocol badges
# Start with sample flows
./cpp learn --input examples/sample-flows.json
# Generate policies
./cpp propose
# Verify policies
./cpp verify
# Generate report
./cpp explain
# Open report in browser
open out/report.html # macOS
xdg-open out/report.html # Linux
start out/report.html # Windows# Use HipsterShop example
./cpp learn --input examples/hipstershop-flows.json
# Generate policies for hipstershop namespace
./cpp propose --namespace hipstershop --output hipstershop-policies.yaml
# Verify and generate report
./cpp verify --input hipstershop-policies.yaml
./cpp explain --flows out/flows.json --policies hipstershop-policies.yaml# Capture flows from Hubble CLI (if available)
hubble observe -o json --since 5m > my-flows.json
# Process flows
./cpp learn --input my-flows.json --output processed-flows.json
./cpp propose --input processed-flows.json --output my-policies.yaml --namespace production
./cpp verify --input my-policies.yaml
./cpp explain --flows processed-flows.json --policies my-policies.yaml --output my-report.htmlcilium-policypilot/
├── cmd/cpp/ # CLI entry point
├── internal/
│ ├── hubble/ # Hubble flow parsing and reading
│ ├── synth/ # Policy synthesis from flows
│ ├── verify/ # Policy validation
│ ├── explain/ # HTML report generation
│ ├── graph/ # Network graph generation
│ └── validate/ # Input validation utilities
├── examples/ # Example flow files
│ ├── sample-flows.json
│ └── hipstershop-flows.json
└── out/ # Generated outputs (gitignored)
graph TB
subgraph "CLI Layer"
CLI[cmd/cpp/main.go<br/>Cobra CLI]
end
subgraph "Internal Packages"
Hubble[internal/hubble/<br/>Flow Parsing]
Synth[internal/synth/<br/>Policy Synthesis]
Verify[internal/verify/<br/>Policy Validation]
Explain[internal/explain/<br/>Report Generation]
Graph[internal/graph/<br/>Network Graph]
Validate[internal/validate/<br/>Input Validation]
end
subgraph "Data Sources"
HubbleJSON[Hubble Flows<br/>JSON Files]
HubbleCLI[Hubble CLI<br/>Future: API]
end
subgraph "Outputs"
Policies[CiliumNetworkPolicy<br/>YAML]
Report[HTML Report<br/>with Graph]
end
CLI -->|learn| Hubble
CLI -->|propose| Synth
CLI -->|verify| Verify
CLI -->|explain| Explain
HubbleJSON --> Hubble
HubbleCLI -.->|future| Hubble
Hubble -->|Parsed Flows| Synth
Synth -->|Policies| Verify
Synth -->|Policies| Explain
Hubble -->|Flows| Explain
Explain --> Graph
Validate --> Hubble
Validate --> Synth
Validate --> Verify
Validate --> Explain
Synth --> Policies
Explain --> Report
style CLI fill:#e1f5ff
style Hubble fill:#fff4e1
style Synth fill:#e8f5e9
style Verify fill:#fce4ec
style Explain fill:#f3e5f5
style Graph fill:#f3e5f5
style Validate fill:#fff9c4
flowchart LR
A[Hubble Flows<br/>JSON] -->|learn| B[Parse & Validate<br/>internal/hubble]
B --> C[Parsed Flows<br/>Metadata Extracted]
C -->|propose| D[Synthesize Policies<br/>internal/synth]
D --> E[CiliumNetworkPolicy<br/>YAML]
E -->|verify| F[Validate Structure<br/>internal/verify]
F --> G{Valid?}
G -->|Yes| H[Policy Ready<br/>for Deployment]
C -->|explain| I[Generate Report<br/>internal/explain]
E -->|explain| I
I --> J[HTML Report<br/>+ Network Graph]
style A fill:#e3f2fd
style C fill:#fff3e0
style E fill:#e8f5e9
style H fill:#c8e6c9
style J fill:#f3e5f5
graph LR
subgraph "Kubernetes Cluster"
K8s[Kubernetes Pods<br/>with Cilium]
Cilium[Cilium<br/>eBPF Dataplane]
HubbleObs[Hubble<br/>Observability]
end
subgraph "PolicyPilot"
CLI2[CLI Tool]
Process[Processing Engine]
end
subgraph "Output"
YAML[Policies YAML]
HTML[HTML Report]
end
K8s -->|Network Traffic| Cilium
Cilium -->|Flow Data| HubbleObs
HubbleObs -->|JSON Export| CLI2
CLI2 --> Process
Process --> YAML
Process --> HTML
YAML -.->|Apply| K8s
style K8s fill:#326ce5,color:#fff
style Cilium fill:#60c6ff,color:#000
style HubbleObs fill:#60c6ff,color:#000
style CLI2 fill:#e1f5ff
style Process fill:#fff4e1
style YAML fill:#e8f5e9
style HTML fill:#f3e5f5
sequenceDiagram
participant User
participant CLI as PolicyPilot CLI
participant Hubble as Hubble Parser
participant Synth as Policy Synthesizer
participant Verify as Policy Validator
participant Explain as Report Generator
participant Graph as Graph Builder
User->>CLI: learn --input flows.json
CLI->>Hubble: ReadFlowsFromFile()
Hubble->>Hubble: Parse flows & extract metadata
Hubble-->>CLI: ParsedFlows[]
CLI-->>User: Flows saved to out/flows.json
User->>CLI: propose --namespace hipstershop
CLI->>Hubble: ReadFlowsFromFile()
Hubble-->>CLI: FlowCollection
CLI->>Synth: SynthesizePolicies(flows)
Synth->>Synth: Group flows by destination
Synth->>Synth: Generate ingress rules
Synth->>Synth: Aggregate ports/protocols
Synth-->>CLI: Policies[]
CLI-->>User: Policies saved to out/policy.yaml
User->>CLI: verify --input policy.yaml
CLI->>Verify: VerifyPolicies(file)
Verify->>Verify: Validate YAML syntax
Verify->>Verify: Check required fields
Verify->>Verify: Validate selectors & rules
Verify-->>CLI: VerificationResult
CLI-->>User: ✓ All policies valid
User->>CLI: explain --flows flows.json --policies policy.yaml
CLI->>Explain: GenerateReport(flows, policies)
Explain->>Graph: GenerateGraph(flows)
Graph-->>Explain: Network Graph
Explain->>Explain: Collect statistics
Explain-->>CLI: ReportData
CLI-->>User: Report saved to out/report.html
flowchart TD
Start([Start: Parsed Flows]) --> Group[Group flows by<br/>destination endpoint]
Group --> Filter{Has destination<br/>labels?}
Filter -->|No| Skip[Skip flow]
Filter -->|Yes| CreateKey[Create endpoint key<br/>namespace + labels]
CreateKey --> CheckGroup{Group exists?}
CheckGroup -->|No| NewGroup[Create new group]
CheckGroup -->|Yes| AddFlow[Add flow to group]
NewGroup --> AddFlow
AddFlow --> MoreFlows{More flows?}
Skip --> MoreFlows
MoreFlows -->|Yes| Group
MoreFlows -->|No| ForEach[For each endpoint group]
ForEach --> ExtractLabels[Extract destination labels<br/>for endpoint selector]
ExtractLabels --> GroupSources[Group flows by<br/>source endpoint]
GroupSources --> AggregatePorts[Aggregate ports &<br/>protocols per source]
AggregatePorts --> CreateRules[Create ingress rules<br/>fromEndpoints + toPorts]
CreateRules --> GenerateYAML[Generate CiliumNetworkPolicy<br/>YAML structure]
GenerateYAML --> MoreGroups{More groups?}
MoreGroups -->|Yes| ForEach
MoreGroups -->|No| End([Output: Policies])
style Start fill:#e3f2fd
style End fill:#c8e6c9
style Group fill:#fff3e0
style CreateRules fill:#e8f5e9
graph LR
subgraph "Input: Hubble Flow"
F1[Flow 1:<br/>frontend → productcatalog<br/>Port: 3550, TCP]
F2[Flow 2:<br/>frontend → productcatalog<br/>Port: 3550, TCP]
F3[Flow 3:<br/>cartservice → productcatalog<br/>Port: 3550, TCP]
end
subgraph "Processing"
P1[Group by destination:<br/>productcatalog]
P2[Group sources:<br/>frontend, cartservice]
P3[Aggregate ports:<br/>3550/TCP]
end
subgraph "Output: CiliumNetworkPolicy"
O1[Endpoint Selector:<br/>app=productcatalogservice]
O2[Ingress Rule 1:<br/>from: frontend<br/>ports: 3550/TCP]
O3[Ingress Rule 2:<br/>from: cartservice<br/>ports: 3550/TCP]
end
F1 --> P1
F2 --> P1
F3 --> P1
P1 --> P2
P2 --> P3
P3 --> O1
P3 --> O2
P3 --> O3
style F1 fill:#e3f2fd
style F2 fill:#e3f2fd
style F3 fill:#e3f2fd
style P1 fill:#fff3e0
style P2 fill:#fff3e0
style P3 fill:#fff3e0
style O1 fill:#e8f5e9
style O2 fill:#e8f5e9
style O3 fill:#e8f5e9
-
Learn: Reads Hubble flow data (JSON format) and extracts key metadata:
- Source/destination pod labels and namespaces
- Ports and protocols (TCP/UDP)
- Flow direction and verdict
- IP addresses and identities
-
Propose: Analyzes flows and generates least-privilege policies:
- Groups flows by destination endpoint (namespace + labels)
- For each destination, groups sources by labels
- Aggregates ports and protocols per source
- Creates ingress rules with
fromEndpointsandtoPorts - Generates valid CiliumNetworkPolicy YAML
-
Verify: Validates generated policies:
- Checks YAML syntax and structure
- Validates required fields (apiVersion, kind, metadata, spec)
- Ensures proper CiliumNetworkPolicy structure
- Validates endpoint selectors (matchLabels format)
- Validates ingress/egress rules and port specifications
-
Explain: Creates visual reports:
- Generates network graph (Mermaid format) showing pod-to-pod connections
- Collects statistics (flows, policies, namespaces, protocols)
- Creates interactive HTML report with embedded graph
- Provides policy summaries and flow analysis
out/flows.json: Parsed and validated flows (same format as input, validated)out/policy.yaml: Generated CiliumNetworkPolicies (multi-document YAML, one policy per document)out/report.html: HTML report with statistics and network graph (self-contained, includes Mermaid.js)
Each generated policy follows this structure:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: <service-name>-policy
namespace: <namespace>
spec:
endpointSelector:
matchLabels:
k8s:app: <service-name>
ingress:
- fromEndpoints:
- matchLabels:
k8s:app: <source-service>
toPorts:
- ports:
- port: "<port>"
protocol: TCP|UDPKey characteristics:
- One policy per destination endpoint
- Ingress rules only (based on observed traffic)
- Least-privilege: only allows observed connections
- Ports and protocols aggregated per source
Writing CiliumNetworkPolicies by hand is error-prone:
- Too tight: Breaks workloads, causes outages
- Too loose: Opens security holes, violates compliance
PolicyPilot helps engineers find the sweet spot by:
- Learning from actual traffic patterns
- Generating least-privilege policies automatically
- Validating policies before deployment
- Visualizing network topology and policies
- Go: 1.23 or higher
- Hubble: Access to Hubble flows (JSON format) or Hubble CLI
- Cilium: Understanding of CiliumNetworkPolicy structure
- Capture sufficient traffic: Collect flows during normal operation to capture all legitimate connections
- Time window: Use a representative time period (e.g., 1 hour of peak traffic)
- Multiple captures: Consider capturing flows at different times to catch periodic connections
# Capture flows during peak hours
hubble observe -o json --since 1h > peak-traffic-flows.json- Namespace filtering: Use
--namespaceto generate policies for specific namespaces - Review before applying: Always review generated policies before applying to production
- Test in staging: Apply policies to a staging environment first
# Generate policies for specific namespace
./cpp propose --namespace production --output prod-policies.yaml
# Review policies
cat prod-policies.yaml
# Apply to staging first
kubectl apply -f prod-policies.yaml -n staging- Always verify: Run
verifybefore applying policies - Check for errors: Review any validation errors or warnings
- Validate manually: For critical services, manually review policy rules
- Gradual rollout: Apply policies gradually, starting with non-critical services
- Monitor impact: Watch for connection issues after applying policies
- Keep backups: Keep original flow data and generated policies for reference
Cause: The flows don't contain the specified namespace, or flows are missing namespace information.
Solution:
# Check namespaces in flows
grep -i "namespace" flows.json | head -5
# Generate policies without namespace filter
./cpp propose --input flows.json
# Or use the correct namespace
./cpp propose --namespace <actual-namespace>Cause: Previous command didn't complete successfully, or file path is incorrect.
Solution:
# Check if files exist
ls -la out/
# Run commands in order: learn → propose → verify → explain
./cpp learn --input examples/sample-flows.json
./cpp propose
./cpp verify
./cpp explainCause: Generated YAML file is corrupted or invalid.
Solution:
# Regenerate policies
./cpp propose --input flows.json --output new-policies.yaml
# Verify the new file
./cpp verify --input new-policies.yamlCause: Browser doesn't support JavaScript, or Mermaid.js CDN is blocked.
Solution:
- Use a modern browser (Chrome, Firefox, Edge)
- Check browser console for errors
- Ensure internet connection (Mermaid.js loads from CDN)
- Check if corporate firewall blocks CDN access
Cause: Flow capture didn't include all necessary connections, or traffic patterns changed.
Solution:
# Capture more comprehensive flows
hubble observe -o json --since 24h > comprehensive-flows.json
# Regenerate policies
./cpp learn --input comprehensive-flows.json
./cpp propose
# Or manually edit policies to add missing rulesCause: Flow capture included unauthorized or malicious traffic.
Solution:
- Review flows before generating policies
- Filter out suspicious flows
- Manually tighten policies after generation
- Use namespace filtering to limit scope
- Ingress-only policies: Currently generates ingress rules only (based on observed traffic to destinations)
- No egress rules: Egress policies are not generated (future enhancement)
- No L7 policies: Only L4 (port/protocol) policies are generated
- No CIDR rules: Policies don't include CIDR-based rules (only pod-to-pod)
- No service account matching: Policies use pod labels, not service accounts
- Single namespace per run: Namespace filtering works, but cross-namespace policies need manual handling
- Egress policy generation
- L7 (HTTP) policy support
- CIDR-based rules
- Service account selectors
- Policy merging and optimization
- Direct Hubble API integration
- Real-time flow capture
- Policy diff and updates
- Large flow files: PolicyPilot can handle thousands of flows efficiently
- Memory usage: Approximately 1-2 MB per 1000 flows
- Processing time: ~100ms per 1000 flows on modern hardware
- Grouping algorithm: O(n) complexity where n is number of flows
- Policy count: One policy per unique destination endpoint
- YAML generation: Efficient YAML marshaling using
gopkg.in/yaml.v3
- For very large flow sets (>10,000 flows), consider filtering by namespace first
- Use namespace filtering to reduce processing time
- Generate reports only when needed (they can be large for many flows)
CiliumNetworkPolicies are Kubernetes network policies enforced by Cilium using eBPF. They control network traffic between pods based on:
- Endpoint selectors: Match pods using labels
- Ingress rules: Control incoming traffic to pods
- Egress rules: Control outgoing traffic from pods
- Port/protocol: Specify allowed ports and protocols (TCP/UDP)
Least-privilege network policies:
- ✅ Improve security: Only allow necessary connections
- ✅ Reduce attack surface: Limit potential paths for attackers
- ✅ Compliance: Meet security requirements and best practices
- ✅ Visibility: Make network dependencies explicit
PolicyPilot generates least-privilege policies by:
- Observing actual traffic: Uses real network flows, not assumptions
- Grouping by destination: Creates one policy per service
- Aggregating sources: Groups multiple sources into ingress rules
- Port aggregation: Combines multiple ports per source when possible
This project was built for the eBPF Summit Hackathon. Contributions welcome!
# Clone repository
git clone https://github.com/prabhakaran-jm/cilium-policypilot.git
cd cilium-policypilot
# Build
go build -o cpp ./cmd/cpp
# Run tests
go test ./...
# Run with verbose output
go test -v ./...cmd/cpp/: CLI entry point and command definitionsinternal/hubble/: Hubble flow parsing and typesinternal/synth/: Policy synthesis logicinternal/verify/: Policy validationinternal/explain/: HTML report generationinternal/graph/: Network graph generationinternal/validate/: Input validation utilities
- Create a feature branch
- Add tests for new functionality
- Update documentation
- Submit a pull request
Apache License 2.0 - see LICENSE file for details.
- Cilium - eBPF-based networking, security, and observability
- Hubble - Network, service & security observability for Kubernetes
- Tetragon - eBPF-based Security Observability and Runtime Enforcement
Built for the eBPF Summit Hackathon 2025. Powered by eBPF and Cilium technologies.
This project participates in the Cilium Technologies category, as it:
- Uses Hubble for network flow observability
- Generates CiliumNetworkPolicies from observed traffic
- Integrates with the Cilium ecosystem
- Enhances Cilium's policy management capabilities
- Educates users about CiliumNetworkPolicies
See SUBMISSION.md for detailed category justification.