System Architecture
kguardian is designed as a distributed system: four core components (Controller, Broker, CLI, UI) plus an audit-mode evaluator (deployed by default) and an optional AI assistant (llm-bridge + mcp-server) work together to observe, analyze, and secure your Kubernetes workloads.Components
Controller
Language: Rust + eBPF (C)Deployment: DaemonSet (one per node)Purpose: Observes kernel-level events
Broker
Language: Rust + Actix-webDeployment: Deployment with PostgreSQLPurpose: Stores and serves telemetry data
CLI
Language: GoDeployment: kubectl pluginPurpose: Generates security policies
UI
Language: React + TypeScriptDeployment: Web applicationPurpose: Visualizes network topology
Evaluator
Deployment: Deployment (on by default; disable with
evaluator.enabled=false)Purpose: Replays observed flows against policies and records would-deny verdictsAI Assistant (Optional)
Deployment: llm-bridge + mcp-server (opt-in via chart values)Purpose: Natural-language queries and conversational policy generation
Data Flow
1. eBPF Monitoring
The Controller attaches eBPF programs to kernel hooks on each node — fentry probes on
tcp_v4_connect, tcp_set_state, udp_sendmsg, and tcp_retransmit_skb, a kprobe/kretprobe pair on inet_csk_accept, and the raw_syscalls/sys_enter tracepoint. When pods make network connections or execute syscalls, eBPF programs capture:- Source/destination IPs and ports
- Protocol (TCP/UDP)
- Syscall names and arguments
- Container network namespace inode
- Timestamp
eBPF runs in the kernel with low overhead, avoiding the need for sidecar proxies or agent injection.
2. Event Enrichment
The Controller’s userspace component:
- Receives events from eBPF via BPF ring buffers
- Queries containerd to map network namespace inodes to container IDs
- Matches containers to Kubernetes pods via the API server
- Enriches events with pod name, namespace, labels, and owner references
3. Data Transmission
Enriched events are sent to the Broker via HTTP POST:
- Network traffic →
/pod/traffic(batched via/pod/traffic/batch) - Pod metadata →
/pod/spec - Syscall data →
/pod/syscalls - Service mappings →
/svc/spec - Pod deletions →
/pod/mark_dead
4. Storage & Indexing
The Broker stores all telemetry in PostgreSQL with indexes on:
- Pod IP address
- Pod name + namespace
- Timestamp (for time-range queries)
- Traffic type (INGRESS/EGRESS)
5. Policy Generation
The CLI queries the Broker API:
- Fetches all traffic for a specific pod
- Identifies unique source/destination IPs
- Resolves IPs to pods/services via the Broker
- Groups traffic by protocol and port
- Deduplicates rules
- Generates K8s/Cilium NetworkPolicy YAML
6. Visualization
The UI fetches data from the Broker and renders:
- An interactive graph of pod-to-pod communication (React Flow)
- Tables of traffic details with filtering
- Live view (polled, ~5s) — the UI re-fetches from the Broker on a short interval
Technology Stack
Controller (Rust + eBPF)
Why Rust?
Why Rust?
- Memory safety without garbage collection (critical for low-level system programming)
- Performance on par with C/C++ for userspace eBPF handling
- libbpf-rs bindings provide excellent eBPF ergonomics
- Tokio async runtime for efficient event processing
eBPF Programs
eBPF Programs
- Written in C, compiled with
clang -target bpf - Use
libbpf-cargoto generate Rust skeleton bindings (.skel.rs) - Attach fentry probes to
tcp_v4_connect,tcp_set_state,udp_sendmsg, andtcp_retransmit_skb; a kprobe/kretprobe pair toinet_csk_accept; and theraw_syscalls/sys_entertracepoint - Use BPF maps for kernel ↔ userspace communication
Kubernetes Integration
Kubernetes Integration
- kube-rs: Rust Kubernetes client for pod watching
- Watches pods on the current node via field selector
- Filters by excluded namespaces (kube-system, kguardian, etc.)
- Handles pod lifecycle events (create, update, delete)
Broker (Rust + Actix-web + PostgreSQL)
API Framework
API Framework
- Actix-web: High-performance HTTP server (thousands of req/sec)
- RESTful API with JSON payloads
- Async request handling with Tokio
- Diesel ORM for type-safe SQL queries
Data Schema
Data Schema
Tables:
pod_details: Pod metadata (name, namespace, IP, labels, spec)svc_details: Service metadata (name, namespace, cluster IP, selectors)pod_traffic: Network connections (src/dst IP, port, protocol, type)pod_syscalls: Syscall observations (pod, syscall names, count, architecture)audit_verdicts: Evaluator would-deny verdicts for observed flowsinstall_info: Installation metadata
Data Retention
Data Retention
audit_verdictsare pruned automatically:broker.audit.retention.days(default 30), withintervalSecondsandbatchSizecontrolling the pruning loop.pod_trafficandpod_syscallsare retained indefinitely.- The cluster-wide
GET /pod/trafficendpoint is capped to protect the broker: 5000 rows by default, up to 20000 via?limit=.
CLI (Go)
Why Go?
Why Go?
- kubectl plugin ecosystem: Natural fit for K8s tooling
- client-go: Official Kubernetes Go client
- cobra: Industry-standard CLI framework
- Cross-platform binaries without dependencies
Policy Generation Logic
Policy Generation Logic
Network policies:
- Query
/pod/traffic/{pod}from Broker - For each unique peer IP, query
/pod/ip/{ip}or/svc/ip/{ip} - Build
NetworkPolicyPeerwithpodSelector+namespaceSelector - Group by direction (ingress/egress) and port/protocol
- Deduplicate rules via JSON marshaling comparison
- Generate YAML with
sigs.k8s.io/yaml
Seccomp Generation Logic
Seccomp Generation Logic
- Query
/pod/syscalls/{pod}from Broker - Extract unique syscall names from aggregated data
- Group by architecture (x86_64, arm64, etc.)
- Generate JSON with
defaultAction: SCMP_ACT_ERRNO - Add
syscallsarray withaction: SCMP_ACT_ALLOW
UI (React + TypeScript)
Frontend Stack
Frontend Stack
- React 19: Modern UI framework
- TypeScript: Type safety for complex state
- Vite: Fast build tooling
- TailwindCSS 4: Utility-first styling
- React Flow: Interactive network graph rendering
Visualization
Visualization
- Pods rendered as collapsible nodes (expand to show containers)
- Edges show traffic direction with arrows
- Namespace-based grouping with color coding
- Interactive filtering by namespace, pod, traffic type
Data Display
Data Display
- Traffic table with sorting and pagination
- Pod details panel with labels and metadata
- Live view (polled, ~5s) via the Broker API
- Dark mode support (matches Cilium Hubble aesthetic)
Deployment Architecture
Standard Deployment (Helm)
High Availability
For production, configure:- Broker replicas: 2-3 for load balancing
- PostgreSQL: Use managed service (RDS, Cloud SQL) or PostgreSQL operator with replication
- Controller: Automatically HA via DaemonSet (one per node)
- UI: 2+ replicas behind ingress/load balancer
Security Considerations
Controller Privileges
Controller Privileges
The Controller requires:
- Privileged container with CAP_BPF added (to load eBPF programs)
- hostNetwork: true (to access the node network namespace)
Data Access
Data Access
- The Broker API is unauthenticated by default, with opt-in bearer-token auth via
broker.auth(BROKER_AUTH_TOKEN);/healthand/metricsstay exempt - The chart can also manage a NetworkPolicy restricting Broker access
- For production, additionally consider:
- Ingress with authentication (OAuth2 proxy, etc.)
- mTLS between components
Data Sensitivity
Data Sensitivity
The PostgreSQL database contains:
- Pod names, namespaces, labels
- IP addresses and ports of communication
- Syscall activity
Performance Characteristics
The chart ships with these default resource requests and limits:For measured numbers from a real deployment, see the reference deployment in the project README.
Scalability
- Controllers: Scale linearly with node count (DaemonSet)
- Broker: Stateless, can add replicas behind a load balancer
- PostgreSQL: Vertical scaling or read replicas for high query loads
- CLI: No scaling concerns (client-side)
- UI: Horizontal scaling behind ingress
- Sharding data by namespace
- Time-windowed queries
- Data aggregation/rollup
Deep Dive: eBPF Monitoring
Learn how eBPF programs capture kernel events
Controller Implementation
Explore the Controller source code
Broker API Reference
View all API endpoints and schemas
Troubleshooting
Diagnose common architecture-related issues