> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiaxoniq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How eBPF works

> Enough kernel detail to answer a security review: what eBPF is, why a program cannot crash your kernel, and what the agent attaches to.

**eBPF** lets a program run inside the Linux kernel, attached to a specific
event, without a kernel module and without patching the kernel. It is the
facility that makes zero-code instrumentation possible: the agent can observe
what your processes do because it is executing at the point where they do it.

This page is the amount of kernel detail needed to answer a security question.
It is not a tutorial.

<Warning>
  **Availability.** The zero-code agent is an early-access distribution. It is
  installable, upgradable and tested, and it is **not yet an integrated part of
  the product**: there is no dashboard page for it, no in-product installer and
  no self-service download. Ask your account contact for access.

  Its telemetry, once flowing, is ordinary OTLP and needs nothing special —
  it appears in Services, Traces and Metrics exactly like SDK telemetry does.
  That is the design rather than a shortcut.
</Warning>

## The model

<Steps>
  <Step title="A program is compiled to eBPF bytecode">
    A restricted instruction set. No unbounded loops, no arbitrary memory
    access, no calling into anything it likes.
  </Step>

  <Step title="The kernel verifier checks it before loading">
    Every possible execution path is analysed. A program that could loop
    forever, read out of bounds, or dereference an unchecked pointer is
    **rejected** — it never runs.
  </Step>

  <Step title="It attaches to an event">
    A kernel function entry, a userspace library call, a network socket, a
    tracepoint.
  </Step>

  <Step title="It runs on that event and writes to a map">
    Bounded work, then a result into a shared memory region.
  </Step>

  <Step title="The agent reads the maps from userspace">
    Aggregates, converts to OTLP, and exports.
  </Step>
</Steps>

<Note>
  **The verifier is the reason this is safe to run in production.** A kernel
  module can do anything and a bug in one panics the machine. An eBPF program
  is proven terminating and memory-safe *before* it is allowed to load. Loading
  failures are loud and non-fatal — the program is refused, and the kernel
  carries on.

  This is the whole difference between eBPF-based agents and the kernel-module
  agents that earned the category its reputation.
</Note>

## What the agent attaches to

| Attachment                              | Purpose                                                                                                         |
| :-------------------------------------- | :-------------------------------------------------------------------------------------------------------------- |
| **uprobes on TLS library functions**    | Observe HTTP requests at the point they are encrypted or decrypted — otherwise everything is opaque ciphertext. |
| **kprobes on kernel network functions** | Connection lifecycle, peers, timing.                                                                            |
| **Socket filters**                      | Network flow metrics *(profile A only)*.                                                                        |
| **TC programs**                         | Injecting trace context on outbound requests *(profile C only)*.                                                |

The TLS hooks are the important one, and they are the source of the sharpest
question in any security review.

<Warning>
  **The agent's position lets it see plaintext.** It hooks `SSL_read` and
  `SSL_write`, so at that boundary it observes decrypted traffic: headers
  including `Authorization`, cookies, request and response bodies, SQL
  statement text.

  What stops that becoming data anyone holds is configuration, not
  incapability: payload capture is **off**, URL paths are reduced to route
  patterns before export, and only metadata leaves the host. The full statement
  of what is sent is in [Security model](/zero-code/security) — read that page
  before you sign anything.
</Warning>

## Why it needs privilege

Loading an eBPF program and attaching probes are privileged kernel operations.
This is not incidental — it is why the agent can see what it sees, and why the
decision about *how much* privilege deserves to be explicit.

The requirement is expressed as Linux **capabilities**, not as root:

| Capability               | Why                                                              |
| :----------------------- | :--------------------------------------------------------------- |
| `CAP_BPF`                | Load eBPF programs. The core requirement.                        |
| `CAP_PERFMON`            | Attach to perf events, and do pointer arithmetic in eBPF.        |
| `CAP_SYS_PTRACE`         | Read `/proc/<pid>/exe` to identify executables and find symbols. |
| `CAP_DAC_READ_SEARCH`    | Read `/proc/self/mem` to determine the running kernel version.   |
| `CAP_CHECKPOINT_RESTORE` | Resolve `/proc` symlinks for process identification.             |
| `CAP_NET_RAW`            | Create `AF_PACKET` sockets for network observation.              |
| `CAP_NET_ADMIN`          | Load TC programs — trace-context injection. *Profile C only.*    |

<Note>
  **`CAP_SYS_ADMIN` is not in any profile.** It is near-equivalent to root. It
  is refused outright for the lower two profiles, and reachable only through an
  explicit opt-in flag on the highest. See
  [Capability profiles](/zero-code/profiles).
</Note>

## Why the kernel version matters

The agent reads kernel data structures whose layout changes between versions.
Rather than compiling a build per kernel, it uses **CO-RE** — compile once, run
everywhere — which relocates field offsets at load time using type information
the kernel publishes about itself, called **BTF**.

That gives you two hard requirements:

* **Kernel 5.8 or newer** (RHEL-family 4.18 excepted, where the features are
  backported).
* **`/sys/kernel/btf/vmlinux` must exist.** Without it there is no type
  information to relocate against.

Both are checked by the preflight tool before anything is installed. See
[Compatibility](/zero-code/compatibility).

## The setting that catches everyone

<Warning>
  **`kernel.perf_event_paranoid` must be 1 or lower.**

  Above that, the kernel denies perf-event access *even when `CAP_PERFMON` is
  granted*. The failure is the worst possible shape: the agent starts, holds
  every capability it asked for, passes its own internal checks, reports
  healthy — and collects nothing at all. There is no error to find.

  ```bash theme={null}
  sudo sysctl -w kernel.perf_event_paranoid=1
  echo 'kernel.perf_event_paranoid=1' | sudo tee /etc/sysctl.d/99-aiaxoniq.conf
  ```

  Preflight treats this as a blocking failure rather than a warning, precisely
  because nothing downstream would tell you.
</Warning>

## What is left behind

Nothing in the kernel. eBPF programs and their maps are released when the
process that loaded them exits. Stopping the agent stops the observation; there
is no module to unload and no reboot to schedule.

## Next

<CardGroup cols={3}>
  <Card title="OpenTelemetry OBI" icon="telescope" href="/zero-code/obi">
    The upstream project, what is pinned, and what this distribution changes.
  </Card>

  <Card title="Security model" icon="shield-halved" href="/zero-code/security">
    Written for a security team: what it sees, sends and never does.
  </Card>

  <Card title="Capability profiles" icon="layer-group" href="/zero-code/profiles">
    Three privilege levels, measured rather than quoted.
  </Card>
</CardGroup>
