{"slug": "show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces", "title": "Show HN: Kguardian – seccomp profiles and NetworkPolicies from eBPF traces", "summary": "Kguardian, a new open-source Kubernetes security tool, generates least-privilege NetworkPolicy, CiliumNetworkPolicy, and seccomp profiles from eBPF traces of pod traffic and syscalls rather than hand-authored rules. The tool uses an eBPF DaemonSet Controller to capture every TCP/UDP connection and syscall per node, a Broker that stores per-pod baselines in PostgreSQL, and a kubectl kguardian plugin that emits policy YAML for a pod, namespace, or cluster; it never applies policies itself, writing files to --output-dir for review. Kguardian also offers an AuditNetworkPolicy CRD that reports flows a policy would deny, cgroup v2 CPU/memory gauges with noisy-neighbour findings, and an optional LLM Bridge AI assistant for querying traffic and syscall data in natural language.", "body_md": "*Least-privilege Kubernetes security policies, generated from what your pods actually do*\n\n[Overview](#-overview) · [In action](#-in-action) · [Features](#-features) · [Architecture](#%EF%B8%8F-architecture) · [Quick Start](#-quick-start) · [Usage](#%EF%B8%8F-usage) · [AI Assistant](#-ai-assistant) · [Compatibility](#-compatibility) · [Performance](#-performance) · [Telemetry](#-telemetry) · [Contributing](#-contributing) · [License](#-license)\n\nkguardian watches pod traffic and syscalls with eBPF, then writes Kubernetes `NetworkPolicy`, `CiliumNetworkPolicy`, and seccomp profiles from what it sees — no hand-authored rules.\n\nIt's built for platform and security teams who want policy-as-code without writing rules by hand: the Controller (an eBPF DaemonSet) captures every TCP/UDP connection and syscall on each node, the Broker stores the per-pod baseline in PostgreSQL, and the `kubectl kguardian` plugin turns that baseline into least-privilege policy YAML for any pod, namespace, or the whole cluster.\n\n|  <sub>**Network Map** — every flow eBPF saw, in one graph: trusted, egress, and would-deny edges for a live namespace (here, Flux).</sub> |  <sub>**Policy Builder** — a least-privilege `NetworkPolicy` or `CiliumNetworkPolicy` written from what the workload actually did.</sub> | \n|  <sub>**Workloads · Seccomp** — per-workload syscall allow-lists with node readiness and drift against the deployed `SeccompProfile`, audit mode by default.</sub> |  <sub>**Policy as code** — export the `SeccompProfile` CR, see the diff against what is deployed, commit it. kguardian never applies anything itself.</sub> | \n\n- **Network Policy generation** — least-privilege Kubernetes`NetworkPolicy` and Cilium`CiliumNetworkPolicy` resources from observed pod-to-pod traffic. Each flow's peer is identified when it is captured, not when a policy is generated, so a recycled pod IP never allow-lists the wrong workload ([how peers are attributed](https://docs.kguardian.dev/concepts/peer-attribution) ).\n- **Seccomp profile generation** — per-workload syscall allowlists derived from runtime traces, exported as a`SeccompProfile` CR you commit; the controller places the file on every node only once you apply it. Capture is tiered (`full` by default, cheap thanks to in-BPF dedup;`high` /`medium` /`low` /`custom` for monitoring-only clusters), and only a`full` capture yields a profile safe to enforce.\n- **Live compute gauges and noisy-neighbour detection** — every pod on the map carries a live CPU/memory gauge from cgroup v2, and the broker raises a finding when a pod is starved (`noisy-neighbor` ,`cpu-contended` ,`memory-pressure` ) or under-provisioned by its own limits (`cpu-throttled` ,`memory-limit-thrash` ). With the optional eBPF scheduler probe it names the pod, system unit or kernel thread that was on the CPU while the victim waited — and it never blames a neighbour for a pod's own CFS throttling ([how it works](https://docs.kguardian.dev/concepts/compute-contention) ).\n- **Policy auditing before enforcement** — the`AuditNetworkPolicy` CRD is byte-identical to an upstream`NetworkPolicy` , but instead of dropping packets the evaluator reports every flow the policy*would* deny. Ship policies with confidence instead of blackholing production.\n- **Flexible targeting** — generate per-pod, per-namespace, or cluster-wide.\n- **Review-first by design** — the CLI writes YAML to`--output-dir` and never applies anything to the cluster; you review and`kubectl apply` the files yourself.\n- **GitOps-friendly output** — plain YAML/JSON files ready for review or a GitOps pipeline.\n- **Optional AI assistant** — query traffic and syscall data in natural language via the LLM Bridge, in the web UI or from your own MCP client.\n\nExample policies for common workloads (nginx, Postgres, kube-dns, Prometheus, Istio sidecar, a Go microservice) live in the [Policy Gallery](https://github.com/kguardian-dev/kguardian/blob/main/docs/policy-gallery). For a comparison with Inspektor Gadget and Security Profiles Operator, see the [docs site](https://docs.kguardian.dev/#comparison-with-other-tools).\n\n```\ngraph LR\n    subgraph \"Each Node\"\n        C[Controller<br/>Rust + eBPF]\n    end\n    B[Broker<br/>Rust + Actix]\n    DB[(PostgreSQL)]\n    E[Evaluator<br/>Go]\n    UI[Web UI<br/>React]\n    CLI[kubectl kguardian<br/>Go]\n\n    C -->|traffic + syscalls| B\n    B --> DB\n    B -->|flows| E\n    E -->|would-deny verdicts| B\n    UI --> B\n    CLI -->|generate policies| B\n\n    style C fill:#4E3AD9,color:#fff\n    style B fill:#6D5CE6,color:#fff\n    style E fill:#6D5CE6,color:#fff\n    style UI fill:#6D5CE6,color:#fff\n    style CLI fill:#3B2BA8,color:#fff\n```\n\n| Component | Language | Runs as | Purpose | \n|---|---|---|---|\n| **Controller** | Rust + eBPF (C) | DaemonSet | Captures every TCP/UDP connection and syscall on each node | \n| **Broker** | Rust (Actix) | Deployment + PostgreSQL | Stores per-pod behavioral baselines and serves the API | \n| **Evaluator** | Go | Deployment | Evaluates live flows against `AuditNetworkPolicy` CRDs and reports would-deny verdicts — without dropping a packet | \n| **CLI** (`kubectl kguardian` ) | Go | kubectl plugin | Generates NetworkPolicies and seccomp profiles from the observed baseline | \n| **Web UI** | React + TypeScript | Deployment | Visualizes traffic, policies, and pod behavior | \n| **LLM Bridge** | TypeScript | Optional Deployment | Natural-language assistant over cluster traffic — runs all tools and policy/seccomp generation in-process, and optionally serves them to external MCP clients ( [llm-bridge/README.md](https://github.com/kguardian-dev/kguardian/blob/main/llm-bridge/README.md) ) | \n\n**Prerequisites:** Kubernetes v1.19+, `kubectl` v1.19+, and Linux kernel **6.2+** on every node that runs the Controller DaemonSet (see [Compatibility](#-compatibility)).\n\nInstall the in-cluster components with Helm, then the `kubectl` plugin:\n\n```\nhelm install kguardian oci://ghcr.io/kguardian-dev/charts/kguardian \\\n  --namespace kguardian --create-namespace\nsh -c \"$(curl -fsSL https://raw.githubusercontent.com/kguardian-dev/kguardian/main/scripts/quick-install.sh)\"\n```\n\nGive the Controller some time to observe real traffic, then generate policies:\n\n```\n# Least-privilege NetworkPolicy for one pod (dry-run, saved to ./policies)\nkubectl kguardian gen networkpolicy my-pod -n default --output-dir ./policies\n\n# Cilium policies for every pod in a namespace\nkubectl kguardian gen netpol --all -n staging --type cilium --output-dir ./policies\n\n# Seccomp profiles for all pods in all namespaces\nkubectl kguardian gen seccomp -A --output-dir ./seccomp\n```\n\nReview the generated YAML, then apply it yourself (`kubectl apply -f ./policies`). Manual download, custom Helm values, Kind setup, verification, upgrades, and uninstall are covered in the [Installation Guide](https://docs.kguardian.dev/installation).\n\nThe plugin follows the standard `kubectl` command structure:\n\n```\nkubectl kguardian gen <networkpolicy|seccomp> [pod-name] [flags]\n```\n\n| Flag | Applies to | Description | \n|---|---|---|\n| `-n, --namespace` | both | Namespace scope (defaults to current context namespace) | \n| `--all` | both | All pods in the selected namespace ( `-a` shorthand: networkpolicy only) | \n| `-A, --all-namespaces` | both | All pods in all namespaces | \n| `--output-dir` | both | Directory for generated files ( `network-policies` /`seccomp-profiles` ) | \n| `-t, --type` | networkpolicy | `kubernetes` (default) or`cilium` | \n| `--dry-run` | networkpolicy | `true` (default). Applying directly is not implemented yet — the CLI always writes files only | \n| `--default-action` | seccomp | Action for unlisted syscalls: `SCMP_ACT_ERRNO` (default),`SCMP_ACT_LOG` ,`SCMP_ACT_KILL` | \n\nFull command reference, including audit workflows and advanced flags, is in the [CLI docs](https://docs.kguardian.dev/cli).\n\nkguardian ships an optional natural-language assistant: ask questions like *\"what has this pod talked to in the last hour?\"* or *\"generate a seccomp profile for the payments namespace\"* from the Web UI. It's a single service, the LLM Bridge (SSE streaming), that reads the broker's data directly and generates policies and seccomp profiles in-process — bring your own API key for OpenAI, Anthropic, Gemini, or GitHub Copilot.\n\n```\nai:\n  enabled: true\n  provider: anthropic          # openai | anthropic | gemini | copilot\n  secret: kguardian-anthropic  # Secret holding the key under `api-key`\n```\n\nRunning an OpenAI-compatible gateway (LiteLLM, vLLM, a proxy)? Add `ai.baseUrl` and `ai.model`. Two things to know: the API key is still required — provider availability is gated on the key alone, so point `ai.secret` at your gateway's virtual key (or a dummy value if it's unauthenticated) — and kguardian appends the request path to your base URL **verbatim**, never adding or stripping `/v1`. See the [AI assistant setup](https://docs.kguardian.dev/installation#ai-assistant).\n\nThe same 23 tools can be served over MCP at `POST /mcp` on the LLM Bridge, so Claude Code — or any MCP client — can read your cluster's observed telemetry and write policies from it. Off by default; enable with `ai.mcp.*`, port-forward, and add one server entry:\n\n```\nkubectl -n kguardian port-forward svc/kguardian-llm-bridge 8080:8080\nclaude mcp add --transport http kguardian http://localhost:8080/mcp \\\n  --header \"Authorization: Bearer $KGUARDIAN_MCP_TOKEN\"\n```\n\nFull walkthrough: [Connect an MCP Client](https://docs.kguardian.dev/guides/mcp-endpoint). Env vars, routes, and local development: [llm-bridge/README.md](https://github.com/kguardian-dev/kguardian/blob/main/llm-bridge/README.md).\n\nThe eBPF Controller requires Linux kernel **6.2 or newer** on every node in the DaemonSet. Verify with `uname -r` before installing.\n\n| Distro | Default kernel | Compatible? | \n|---|---|---|\n| Ubuntu 24.04 | 6.8 | ✅ | \n| Ubuntu 22.04 | 5.15 | ❌ (needs HWE 6.2+) | \n| RHEL 9 | 5.14 | ❌ | \n| Amazon Linux 2023 | 6.1 | ❌ (needs kernel-6.12+ AMI) | \n| Debian 12 | 6.1 | ❌ (needs backports) | \n| Talos / Bottlerocket | usually 6.1+ | check distro version | \n\nKernel versions reflect the GA/server defaults shipped by each distro as of May 2026; newer kernels are typically available via each distro's opt-in channels.\n\nIPv4, IPv6, and dual-stack clusters are all supported. The Controller reads both `AF_INET` and `AF_INET6` sockets, and policy generation emits `/32` or `/128` ipBlocks per peer — a dual-stack pod gets both families in one policy.\n\nThings to know:\n\n- **Dual-stack pods and Services are tracked on every address** , not just the primary one in`.status.podIP` /`.spec.clusterIP` . A peer is therefore resolved to a`podSelector` regardless of which family the traffic used.\n- **Nodes built with `CONFIG_IPV6=n`** are handled: the IPv6 socket fields are read behind a CO-RE existence guard, so the Controller loads and runs normally on such kernels — it simply never sees v6 flows there.\n- **Every service listener is dual-stack.** The broker, frontend, llm-bridge and evaluator bind the IPv6 unspecified address (accepting IPv4 as v4-mapped) and fall back to IPv4-only on kernels without IPv6 — so the stack serves IPv4-only, dual-stack, and IPv6-only clusters alike. The broker's`LISTEN_ADDR` env still binds verbatim when set.\n- **Kernels with IPv6 as a module but no module BTF** (kernels older than 5.11, or built with`CONFIG_DEBUG_INFO_BTF_MODULES=n` — Debian 11's 5.10 is the common case) can't attach the IPv6 UDP probes. The Controller detects this at startup, logs a warning, and runs with those probes disabled rather than failing; IPv6 TCP capture is unaffected.\n- **UDP flows are captured from connected sockets** (glibc's DNS resolver connects, so pod DNS is covered on both families). Unconnected`sendto()` datagrams carry no destination on the socket at the probe point and are not captured — the same behaviour IPv4 has always had, notable mainly for musl-based (Alpine) resolvers.\n\nA generated policy is only as complete as what was observed. If a workload speaks both families but was only exercised over one during the observation window, the policy will reflect that — review before enforcing, as always.\n\nReference figures from a real-world deployment — a 3-node cluster (18 vCPU / 47 GiB RAM per node, Cilium CNI) observing 234 pods across 26 namespaces of mixed traffic:\n\n- **Controller (eBPF DaemonSet):** ~60 MiB memory and ~0.1–0.6 vCPU per node, tracking the node's connection/syscall rate.\n- **Broker + evaluator:** evaluator ~26 MiB / <0.01 vCPU idle; broker sized at 512 MiB request / 2 GiB limit with plenty of headroom at this scale.\n- **PostgreSQL** is the dominant consumer (~0.4–2 GiB RAM here, CPU spiking under ingest + autovacuum) — size it generously.\n- **Storage growth is dedup-bounded:** once a workload's flow set is learned, new rows drop to ~0/min in steady state. The database grows with*new* behavior, not with time or traffic volume;`broker.audit.retention.days` caps the audit-verdict history.\n\nThis is one measured data point, not a synthetic sweep — treat it as an order-of-magnitude envelope. Expect numbers to scale with flow cardinality, not raw pod count.\n\nThe broker performs a daily anonymous version check-in that powers the UI's update notice and is the project's only usage signal. Exactly six fields are sent — a random install UUID, broker/chart/Kubernetes versions, node count, and CPU architecture; no cluster names, IPs, or workload data, ever. It's on by default, announced at install time, documented field-by-field in the [telemetry docs](https://docs.kguardian.dev/telemetry), and disabled with `--set telemetry.enabled=false`.\n\nContributions are welcome — read the [contributing guide](https://github.com/kguardian-dev/kguardian/blob/main/CONTRIBUTING.md) to get started. The release process and versioning strategy are documented in [RELEASES.md](https://github.com/kguardian-dev/kguardian/blob/main/RELEASES.md), and security reports go through [SECURITY.md](https://github.com/kguardian-dev/kguardian/blob/main/SECURITY.md).\n\nLicensed under the [Business Source License 1.1](https://github.com/kguardian-dev/kguardian/blob/main/LICENSE):\n\n- **Free for** development, testing, evaluation, and non-production/non-commercial use\n- **Commercial use** requires a commercial license (contact the licensors)\n- **Converts to** Apache License 2.0 on January 1, 2029", "url": "https://wpnews.pro/news/show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces", "canonical_source": "https://github.com/kguardian-dev/kguardian", "published_at": "2026-09-30 07:36:02+00:00", "updated_at": "2026-09-30 07:49:15.955779+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents"], "entities": ["Kguardian", "Kubernetes", "eBPF", "CiliumNetworkPolicy", "PostgreSQL", "Inspektor Gadget", "Security Profiles Operator", "Flux"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces", "markdown": "https://wpnews.pro/news/show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces.md", "text": "https://wpnews.pro/news/show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces.txt", "jsonld": "https://wpnews.pro/news/show-hn-kguardian-seccomp-profiles-and-networkpolicies-from-ebpf-traces.jsonld"}}