If an MCP server can spawn /bin/sh, a prompt injection is basically a remote shell on your host with extra steps.
While researching AI agent runtime security for xSypher, I kept running into the same architectural wall. Static container profiles like AppArmor or seccomp break almost immediately on autonomous AI agent workloads because agents are dynamic by design—they legitimately write code, invoke interpreters, and execute subprocesses.
On the flip side, standard user-space syscall tracers usually alert you 50 to 2,000 ms after the syscall fires. By the time an alert lands on mcp-server -> python3 -> sh -> curl, the AWS or GCP cloud metadata (IMDS) token at 169.254.169.254 has already left the host.
The signal is not the individual syscall. It is the process ancestry behind it and the network destination in front of it—and containment has to happen synchronously before the socket opens.
To solve this at the Linux syscall boundary without running another bloated, monolithic root daemon, I built and open-sourced xSypher-Stream (v2.0.0).
anwariqbaldawar
/
xSypher-Stream-Zero-Trust-Kernel-log-Telemetry
Kernel-verified runtime defense for AI agent & MCP hosts using eBPF CO-RE telemetry and inline BPF LSM enforcement.
xSypher-Stream
Kernel-verified runtime defence for AI agent hosts.
eBPF CO-RE telemetry, a policy decision in user space, an inline LSM denial in the kernel.
An injected tool call cannot reach the network if the kernel refuses the syscall first
Quick start · The problem · Comparison · Architecture · Detections · Compliance · Benchmarks · Deployment · Validation · Docs · Contributing
Ten-second quickstart
From a source checkout (Python 3.10+):
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt && PYTHONPATH=src .venv/bin/python tests/simulate_mcp_attack.py --events 10000
This runs real user-space socket transport and simulated kernel events, not live kernel enforcement.
For the native collector, install the prerequisites below, then run
cmake -S . -B build && cmake --build build -j2.
The npm bootstrap package is unpublished; registry installation is not a supported quickstart.
The problem
An MCP server publishes tools to a language model. The model calls those tools with…
Why Traditional Container Security Misses AI Agent Breakouts
When an LLM agent or Model Context Protocol (MCP) server processes untrusted external input, every individual step of an exploit chain looks normal to traditional controls:
-
Subprocess execution is expected: Developer and ops agents legitimately spawn
git,bash,python3, ornode. -
Living-off-the-land binaries exist in the image: Standard base images carry
/bin/sh,curl, and standard file utilities. - Outbound egress is open: Agents need external network access to reach model APIs, package registries, and documentation endpoints.
If you rely on asynchronous user-space detection (ring buffer -> user-space parser -> rule engine -> kill -9), you are racing the kernel scheduler. A hijacked curl http://169.254.169 request completes a local link-local TCP handshake in microseconds. To stop credential exfiltration, enforcement must live inside the kernel LSM hook itself.
Architecture: Splitting Kernel Privilege from Policy Evaluation
Most runtime security tools run their entire rule parsing and telemetry pipeline inside a single privileged process. If that parser has a memory safety bug or logic flaw, the attacker compromises a root daemon.
In xSypher-Stream, I separated kernel collection from threat evaluation across a strict binary wire contract (ABI v3, magic 0x58535950):
1. Kernel Telemetry Plane (5 eBPF CO-RE Tracepoints)
Five eBPF CO-RE programs attach to kernel tracepoints and emit fixed 656-byte kernel_event_t structs into a 16 MiB BPF ring buffer:
-
tp/syscalls/sys_enter_execve— Captures binary path, arguments, UID/GID, and cgroup ID. -
tp/syscalls/sys_enter_connect— Captures outbound IPv4/IPv6 destination addresses and ports. -
tp/syscalls/sys_enter_memfd_create— Flags anonymous in-memory file creation used in fileless ELF execution. -
tp/sched/sched_process_fork— Tracks parent-to-child PID creation in real time. -
tp/sched/sched_process_exit— Cleans up exited PIDs from the lineage state.
2. Inline Enforcement Plane (5 BPF LSM Hooks)
Five BPF LSM programs attach directly to security decision points in the kernel and check pinned BPF maps (quarantined_pids, quarantined_cgroups, blocked_ipv4):
-
lsm/bprm_check_security— Denies binary execution (-EPERM) for quarantined PIDs or cgroups beforeexecvecompletes. -
lsm/socket_connect— Blocks outbound socket connections (-EACCES) to blacklisted IPs (such as Cloud IMDS169.254.169.254) or from quarantined processes. -
lsm/file_open— Blocks unauthorized reads to sensitive host paths (/etc/shadow,/proc/$pid/environ, SSH keys). -
lsm/task_kill— Prevents quarantined processes from signaling or terminating security monitors. -
lsm/bpf— Tamper-protection hook that denies unauthorized processes from modifying or unloading pinned xSypher BPF maps and programs.
3. Capability-Scoped C++20 Collector (xsypher-collector)
The C++20 collector is the only privileged user-space binary, scoped strictly to CAP_BPF and CAP_PERFMON.
- It polls the 16 MiB kernel ring buffer via
epoll(ring_buffer__poll()). - It wraps each 656-byte
kernel_event_tinside an 80-byte transport header to form a fixed 736-bytewire_event_msg_tframe. - It streams frames over an
AF_UNIX(SOCK_SEQPACKET) local IPC socket and listens for validated 32-bytewire_policy_cmd_tcommands to update the kernel BPF maps viabpf_map_update_elem().
4. Zero-Capability Python Threat Engine (xsypher-engine)
The Python 3.10+ asyncio engine runs with zero Linux capabilities (NoNewPrivileges=true).
-
O(depth) Lineage Graph: Maintains a 100,000-PID LRU process ancestry graph in memory, resolving up to 8 ancestor hops (
mcp-server -> python3 -> sh -> curl) on every incoming event. -
6 Shipped MITRE ATT&CK Rules: Evaluates lineage and syscall parameters against YAML rules covering MCP shell breakouts (
T1059.004), Cloud IMDS credential theft (T1552.005),/etc/shadowand environment harvesting (T1003.008), filelessmemfdexecution (T1620), recon tools (T1105), and suspicious C2 egress ports (T1071). -
Tamper-Evident Audit Ledger: Every alert is written to an append-only JSONL log where each record includes a forward-chained SHA-256 hash (
prev_hash + current_payload) verifiable viaxsypher verify-log.
The Fixed Binary Wire Contract (ABI v3)
To eliminate serialization overhead (no JSON or Protobuf parsing on the hot path) and prevent parser bugs across the C++/Python boundary, both sides enforce a compile-time verified binary layout defined in include/xsypher_abi.h:
-
kernel_event_t— 656 Bytes (Kernel BPF Ring Buffer -> C++20 Collector) -
wire_event_msg_t— 736 Bytes (80-Byte Transport Header + 656-Byte Event, Collector -> Python Engine) -
wire_policy_cmd_t— 32 Bytes (Quarantine / Block Command, Python Engine -> Collector -> BPF Maps)
Running make verify compiles a C offset inspector against include/xsypher_abi.h and asserts byte-for-byte parity with the Python ctypes.Structure definitions before any test suite runs.
Engineering Honesty: What Works Today vs. Live-Kernel Gotchas
When releasing security tooling, I believe in documenting exact boundaries rather than hiding behind marketing claims:
-
What passes in CI today: User-space simulation (
~2.1 msend-to-end containment latency across 5 multi-stage exploit chains), C/Python ABI layout parity (make verify), and 63pytestunit and integration tests pass cleanly. -
The BPF LSM Boot Prerequisite: Having
CONFIG_BPF_LSM=ycompiled into your Linux kernel is necessary, but not sufficient by itself. On stock Ubuntu 22.04/24.04 and most standard cloud images, thebpfmodule is omitted from/sys/kernel/security/lsmat boot. Whenbpfis not in the active boot LSM list (lsm=lockdown,capability,landlock,yama,apparmor,bpf),libbpfcan load and attach LSM programs without returning an error, yet the kernel will never invoke them on the syscall path.
Before enabling --enforce-kernel in production, always run xsypher doctor to verify /sys/kernel/security/lsm and baseline your workload in audit-only mode on a dedicated node.
Try It in 10 Seconds (Zero Root Privileges Required)
You do not need a custom kernel, BTF, or root access to test the binary wire protocol, O(depth) lineage graph, and MITRE ATT&CK rule engine. The built-in simulation harness replays 10,000 synthetic syscalls interleaved with 5 multi-stage attack chains over a real AF_UNIX SOCK_SEQPACKET pair:
git clone https://github.com
cd xSypher-Stream-Zero-Trust-Kernel-log-Telemetry
pip install -e .
xsypher simulate 10000
Source Code & Full Architectural Audit
- GitHub Repository (Apache-2.0 / GPL-2.0): anwariqbaldawar/xSypher-Stream-Zero-Trust-Kernel-log-Telemetry
- Full Source-Level Architecture & Rollout Audit on xSypher: xSypher-Stream: Inline eBPF & BPF LSM Kernel Defense for AI Agents
If you are working with eBPF CO-RE, Linux LSMs, or sandboxing autonomous AI agents, I would genuinely appreciate your critique on the collector/engine privilege split and wire ABI design!

Top comments (0)