960 lines
103 KiB
Markdown
960 lines
103 KiB
Markdown
# Runtime Agents Architecture
|
|
|
|
## Overview
|
|
|
|
This document describes the runtime observation layer in StellaOps, including eBPF-based kernel instrumentation, container lifecycle monitoring, and signal aggregation. Runtime evidence provides the highest-confidence reachability determination for policy decisions.
|
|
|
|
---
|
|
|
|
## Runtime Observation Stack
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ RUNTIME OBSERVATION STACK │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ APPLICATION LAYER │
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Container 1 │ │ Container 2 │ │ Container 3 │ │ Container N │ │
|
|
│ │ (app:v1) │ │ (api:v2) │ │ (worker) │ │ (...) │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
│ │ │ │ │ │
|
|
│ └────────────────┴────────────────┴────────────────┘ │
|
|
│ │ │
|
|
│ [Function Calls] │
|
|
│ [System Calls] │
|
|
│ [Network I/O] │
|
|
│ │ │
|
|
└────────────────────────────────────┼────────────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────────────────┼────────────────────────────────────────────────┐
|
|
│ KERNEL SPACE │
|
|
│ │ │
|
|
│ ┌─────────────────┐ ┌────────▼────────┐ ┌─────────────────┐ │
|
|
│ │ kprobes │ │ eBPF VM │ │ tracepoints │ │
|
|
│ │ (syscalls) │◄───┤ (verified │───►│ (scheduler, │ │
|
|
│ │ │ │ bytecode) │ │ network) │ │
|
|
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
|
|
│ │ │ │ │
|
|
│ └──────────────────────┼──────────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────────▼───────────────┐ │
|
|
│ │ eBPF Ring Buffer │ │
|
|
│ │ (per-CPU, lock-free) │ │
|
|
│ └───────────────┬───────────────┘ │
|
|
│ │ │
|
|
└────────────────────────────────────┼────────────────────────────────────────────────┘
|
|
│
|
|
│ [perf events]
|
|
│
|
|
┌────────────────────────────────────┼────────────────────────────────────────────────┐
|
|
│ USER SPACE │
|
|
│ │ │
|
|
│ ┌─────────────────────▼─────────────────────┐ │
|
|
│ │ RuntimeSignalCollector │ │
|
|
│ │ (StellaOps.Signals) │ │
|
|
│ ├───────────────────────────────────────────┤ │
|
|
│ │ • Perf event polling │ │
|
|
│ │ • Symbol resolution (DWARF/kallsyms) │ │
|
|
│ │ • Stack unwinding │ │
|
|
│ │ • Container ID correlation (cgroup) │ │
|
|
│ │ • Event batching and compression │ │
|
|
│ └─────────────────────┬─────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────▼─────────────────────┐ │
|
|
│ │ ZastavaObserver │ │
|
|
│ │ (Container Lifecycle) │ │
|
|
│ ├───────────────────────────────────────────┤ │
|
|
│ │ • Container create/start/stop events │ │
|
|
│ │ • Image digest extraction │ │
|
|
│ │ • Runtime posture evaluation │ │
|
|
│ │ • Label/annotation parsing │ │
|
|
│ └─────────────────────┬─────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────▼─────────────────────┐ │
|
|
│ │ RuntimeSignalNormalizer │ │
|
|
│ │ (Event Processing) │ │
|
|
│ ├───────────────────────────────────────────┤ │
|
|
│ │ • Deduplicate events │ │
|
|
│ │ • Aggregate call counts │ │
|
|
│ │ • Map to package PURLs │ │
|
|
│ │ • Enrich with SBOM context │ │
|
|
│ └─────────────────────┬─────────────────────┘ │
|
|
│ │ │
|
|
└────────────────────────────────────┼────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ STORAGE LAYER │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ Hot Symbol Index │ │
|
|
│ │ (PostgreSQL: signals.hot_symbols) │ │
|
|
│ │ │ │
|
|
│ │ image_digest │ function_name │ purl │ invocation_count │ last_observed │ │
|
|
│ │ ─────────────┼───────────────┼──────┼──────────────────┼───────────────── │ │
|
|
│ │ sha256:abc.. │ lodash.merge │ npm/..│ 1,247 │ 2024-12-29T10:00 │ │
|
|
│ │ sha256:abc.. │ lodash.get │ npm/..│ 8,923 │ 2024-12-29T10:01 │ │
|
|
│ │ sha256:def.. │ axios.request │ npm/..│ 456 │ 2024-12-29T09:55 │ │
|
|
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## eBPF Agent Architecture
|
|
|
|
### Probe Types
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ eBPF PROBE TYPES │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ KPROBES / KRETPROBES │ │
|
|
│ │ │ │
|
|
│ │ Purpose: Trace kernel function entry/exit │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Syscall Tracing │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ kprobe/sys_execve → New process execution │ │ │
|
|
│ │ │ kprobe/sys_openat → File access │ │ │
|
|
│ │ │ kprobe/sys_connect → Network connection │ │ │
|
|
│ │ │ kprobe/sys_socket → Socket creation │ │ │
|
|
│ │ │ kprobe/sys_read → File/socket reads │ │ │
|
|
│ │ │ kprobe/sys_write → File/socket writes │ │ │
|
|
│ │ │ kprobe/sys_mmap → Memory mapping │ │ │
|
|
│ │ │ kprobe/sys_clone → Process/thread creation │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ TRACEPOINTS │ │
|
|
│ │ │ │
|
|
│ │ Purpose: Stable kernel instrumentation points │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Category │ Tracepoint │ Data │ │ │
|
|
│ │ │ ──────────────────┼───────────────────────────┼──────────────────│ │ │
|
|
│ │ │ Scheduler │ sched:sched_process_exec │ New execution │ │ │
|
|
│ │ │ Scheduler │ sched:sched_switch │ Context switch │ │ │
|
|
│ │ │ Network │ net:net_dev_xmit │ Packet TX │ │ │
|
|
│ │ │ Network │ sock:inet_sock_set_state │ TCP state │ │ │
|
|
│ │ │ Filesystem │ ext4:ext4_da_write_begin │ Write start │ │ │
|
|
│ │ │ Memory │ kmem:kmalloc │ Allocation │ │ │
|
|
│ │ │ Security │ security:security_* │ LSM hooks │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ UPROBES │ │
|
|
│ │ │ │
|
|
│ │ Purpose: Trace userspace function entry/exit │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Library/Function Tracing │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc │ │ │
|
|
│ │ │ uprobe:/usr/lib/libssl.so:SSL_read │ │ │
|
|
│ │ │ uprobe:/usr/lib/libcrypto.so:EVP_EncryptFinal │ │ │
|
|
│ │ │ uprobe:/path/to/app:vulnerable_function │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Dynamic attachment based on: │ │ │
|
|
│ │ │ • SBOM analysis (known vulnerable functions) │ │ │
|
|
│ │ │ • Static call graph (entry points to vulnerable code) │ │ │
|
|
│ │ │ • Symbol resolution from DWARF/debug info │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ USDT PROBES │ │
|
|
│ │ │ │
|
|
│ │ Purpose: User Statically Defined Tracing (application-level) │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Runtime-Specific Probes │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Node.js: │ │ │
|
|
│ │ │ usdt:/usr/bin/node:http__server__request │ │ │
|
|
│ │ │ usdt:/usr/bin/node:gc__start │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Python: │ │ │
|
|
│ │ │ usdt:/usr/bin/python3:function__entry │ │ │
|
|
│ │ │ usdt:/usr/bin/python3:function__return │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ JVM: │ │ │
|
|
│ │ │ usdt:libjvm.so:method__entry │ │ │
|
|
│ │ │ usdt:libjvm.so:gc__begin │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Event Data Structures
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ eBPF EVENT DATA STRUCTURES │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ FunctionCallEvent │ │
|
|
│ │ │ │
|
|
│ │ struct function_call_event { │ │
|
|
│ │ u64 timestamp_ns; // Kernel monotonic timestamp │ │
|
|
│ │ u32 pid; // Process ID │ │
|
|
│ │ u32 tid; // Thread ID │ │
|
|
│ │ u64 cgroup_id; // Container cgroup (for correlation) │ │
|
|
│ │ u32 uid; // User ID │ │
|
|
│ │ char comm[16]; // Process name │ │
|
|
│ │ char func_name[64]; // Function name (if resolved) │ │
|
|
│ │ u64 func_addr; // Function address (for offline resolution) │ │
|
|
│ │ u64 caller_addr; // Return address (call site) │ │
|
|
│ │ u64 stack_id; // Stack trace ID (BPF_MAP_TYPE_STACK_TRACE) │ │
|
|
│ │ u64 latency_ns; // Function execution time (kretprobe) │ │
|
|
│ │ u8 event_type; // ENTRY(0), EXIT(1), ERROR(2) │ │
|
|
│ │ }; │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ SyscallEvent │ │
|
|
│ │ │ │
|
|
│ │ struct syscall_event { │ │
|
|
│ │ u64 timestamp_ns; // Kernel monotonic timestamp │ │
|
|
│ │ u32 pid; // Process ID │ │
|
|
│ │ u32 tid; // Thread ID │ │
|
|
│ │ u64 cgroup_id; // Container cgroup │ │
|
|
│ │ u32 syscall_nr; // Syscall number │ │
|
|
│ │ u64 args[6]; // Syscall arguments │ │
|
|
│ │ i64 ret; // Return value │ │
|
|
│ │ u64 latency_ns; // Syscall duration │ │
|
|
│ │ u64 stack_id; // Stack trace ID │ │
|
|
│ │ }; │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ NetworkEvent │ │
|
|
│ │ │ │
|
|
│ │ struct network_event { │ │
|
|
│ │ u64 timestamp_ns; │ │
|
|
│ │ u32 pid; │ │
|
|
│ │ u64 cgroup_id; │ │
|
|
│ │ u8 protocol; // TCP(6), UDP(17) │ │
|
|
│ │ u8 direction; // INBOUND(0), OUTBOUND(1) │ │
|
|
│ │ u32 src_addr; // Source IPv4 (or first 4 bytes of IPv6) │ │
|
|
│ │ u32 dst_addr; // Destination IPv4 │ │
|
|
│ │ u16 src_port; │ │
|
|
│ │ u16 dst_port; │ │
|
|
│ │ u64 bytes; // Data transferred │ │
|
|
│ │ u8 state; // TCP state (ESTABLISHED, SYN_SENT, etc.) │ │
|
|
│ │ }; │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Zastava Container Observer
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ ZASTAVA CONTAINER OBSERVER │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ ARCHITECTURE │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────────────────────────┐ │ │
|
|
│ │ │ Container Runtime │ │ │
|
|
│ │ │ ┌─────────┐ ┌─────────────────┐│ │ │
|
|
│ │ │ │ Docker │ │ containerd ││ │ │
|
|
│ │ │ │ Engine │ │ ││ │ │
|
|
│ │ │ └────┬────┘ └────────┬────────┘│ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ └───────┼───────────────┼─────────┘ │ │
|
|
│ │ │ │ │ │
|
|
│ │ ┌──────────▼───────────────▼──────────┐ │ │
|
|
│ │ │ ZastavaObserver │ │ │
|
|
│ │ │ (Event Subscriber) │ │ │
|
|
│ │ ├─────────────────────────────────────┤ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Connects to: │ │ │
|
|
│ │ │ • /var/run/docker.sock │ │ │
|
|
│ │ │ • /run/containerd/containerd.sock │ │ │
|
|
│ │ │ • /run/crio/crio.sock │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Listens for: │ │ │
|
|
│ │ │ • container.create │ │ │
|
|
│ │ │ • container.start │ │ │
|
|
│ │ │ • container.stop │ │ │
|
|
│ │ │ • container.die │ │ │
|
|
│ │ │ • image.pull │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────┬────────────────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ▼ │ │
|
|
│ │ ┌─────────────────────────────────────┐ │ │
|
|
│ │ │ ContainerLifecycleEvent │ │ │
|
|
│ │ ├─────────────────────────────────────┤ │ │
|
|
│ │ │ event_type: CREATE|START|STOP|DIE │ │ │
|
|
│ │ │ container_id: string │ │ │
|
|
│ │ │ image_ref: string │ │ │
|
|
│ │ │ image_digest: sha256:... │ │ │
|
|
│ │ │ labels: map<string,string> │ │ │
|
|
│ │ │ annotations: map<string,string> │ │ │
|
|
│ │ │ env_vars: string[] (filtered) │ │ │
|
|
│ │ │ pid: u32 (on start) │ │ │
|
|
│ │ │ cgroup_path: string │ │ │
|
|
│ │ │ started_at: timestamp │ │ │
|
|
│ │ │ stopped_at: timestamp │ │ │
|
|
│ │ │ exit_code: i32 │ │ │
|
|
│ │ │ oom_killed: bool │ │ │
|
|
│ │ └─────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ RUNTIME POSTURE EVALUATION │ │
|
|
│ │ │ │
|
|
│ │ On container START, Zastava evaluates the runtime observation posture: │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Posture │ Observation Level │ Prerequisites │ │ │
|
|
│ │ ├───────────────────────┼──────────────────────┼─────────────────────┤ │ │
|
|
│ │ │ None │ No observation │ eBPF disabled │ │ │
|
|
│ │ │ Passive │ Lifecycle only │ Docker socket only │ │ │
|
|
│ │ │ ActiveTracing │ Syscalls + network │ eBPF + kprobes │ │ │
|
|
│ │ │ EbpfDeep │ + function calls │ + uprobes enabled │ │ │
|
|
│ │ │ FullInstrumentation │ + USDT + coverage │ + debug symbols │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ Posture is determined by: │ │
|
|
│ │ 1. Kernel capabilities (CAP_BPF, CAP_SYS_ADMIN) │ │
|
|
│ │ 2. Available probe types │ │
|
|
│ │ 3. Container annotations (stellaops.io/observe-level) │ │
|
|
│ │ 4. Image debug symbol availability │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Signal Processing Pipeline
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ SIGNAL PROCESSING PIPELINE │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Raw Events │
|
|
│ (millions/sec) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ STAGE 1: FILTERING │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ In-Kernel Filtering (eBPF maps) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ • Filter by cgroup_id (only monitored containers) │ │ │
|
|
│ │ │ • Filter by syscall type (only security-relevant) │ │ │
|
|
│ │ │ • Rate limiting per-container (prevent flood) │ │ │
|
|
│ │ │ • Sampling for high-frequency events │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────┬──────────────┘ │
|
|
│ │ │
|
|
│ Filtered Events │ │
|
|
│ (thousands/sec) │ │
|
|
│ │◄────────────────────────────────────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ STAGE 2: ENRICHMENT │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Symbol Resolution │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ func_addr: 0x7f3a4b5c6d7e │ │ │
|
|
│ │ │ ↓ │ │ │
|
|
│ │ │ Resolve via: │ │ │
|
|
│ │ │ 1. /proc/<pid>/maps (memory mappings) │ │ │
|
|
│ │ │ 2. Symbol table cache (from SBOM binaries) │ │ │
|
|
│ │ │ 3. DWARF debug info (if available) │ │ │
|
|
│ │ │ 4. kallsyms (for kernel symbols) │ │ │
|
|
│ │ │ ↓ │ │ │
|
|
│ │ │ func_name: "lodash.template" │ │ │
|
|
│ │ │ module: "/app/node_modules/lodash/lodash.js" │ │ │
|
|
│ │ │ purl: "pkg:npm/lodash@4.17.20" │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Container Correlation │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ cgroup_id: 12345678 │ │ │
|
|
│ │ │ ↓ │ │ │
|
|
│ │ │ Lookup in Zastava registry: │ │ │
|
|
│ │ │ ↓ │ │ │
|
|
│ │ │ container_id: "abc123def456" │ │ │
|
|
│ │ │ image_digest: "sha256:789..." │ │ │
|
|
│ │ │ scan_id: "scan-xyz" (from label) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────┬──────────────────┘ │
|
|
│ │ │
|
|
│ Enriched Events │ │
|
|
│ (hundreds/sec) │ │
|
|
│ │◄─────────────────────────────────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ STAGE 3: AGGREGATION │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Time-Window Aggregation (1-minute windows) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Key: (image_digest, purl, function_name) │ │ │
|
|
│ │ │ Value: AggregatedMetrics { │ │ │
|
|
│ │ │ invocation_count: u64, │ │ │
|
|
│ │ │ unique_callers: HashSet<caller_addr>, │ │ │
|
|
│ │ │ total_latency_ns: u64, │ │ │
|
|
│ │ │ max_latency_ns: u64, │ │ │
|
|
│ │ │ sample_stack: Option<StackTrace>, │ │ │
|
|
│ │ │ first_seen: Timestamp, │ │ │
|
|
│ │ │ last_seen: Timestamp, │ │ │
|
|
│ │ │ } │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────┬──────────────────┘ │
|
|
│ │ │
|
|
│ Aggregated Records │ │
|
|
│ (per function per minute) │ │
|
|
│ │◄─────────────────────────────────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ STAGE 4: PERSISTENCE │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ PostgreSQL: signals.hot_symbols │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ INSERT INTO signals.hot_symbols │ │ │
|
|
│ │ │ (image_digest, function_name, purl, invocation_count, ...) │ │ │
|
|
│ │ │ ON CONFLICT (image_digest, function_name) │ │ │
|
|
│ │ │ DO UPDATE SET │ │ │
|
|
│ │ │ invocation_count = hot_symbols.invocation_count + EXCLUDED.count,│ │ │
|
|
│ │ │ last_observed = EXCLUDED.last_observed, │ │ │
|
|
│ │ │ sample_stack = COALESCE(EXCLUDED.sample_stack, hot_symbols....) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Hot Symbol Index Schema
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ HOT SYMBOL INDEX SCHEMA │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ TABLE: signals.hot_symbols │ │
|
|
│ │ │ │
|
|
│ │ CREATE TABLE signals.hot_symbols ( │ │
|
|
│ │ -- Identity │ │
|
|
│ │ id BIGSERIAL PRIMARY KEY, │ │
|
|
│ │ image_digest TEXT NOT NULL, │ │
|
|
│ │ function_name TEXT NOT NULL, │ │
|
|
│ │ module TEXT, -- Library/file containing func │ │
|
|
│ │ purl TEXT, -- Package URL for module │ │
|
|
│ │ │ │
|
|
│ │ -- Observation metrics │ │
|
|
│ │ invocation_count BIGINT DEFAULT 0, │ │
|
|
│ │ unique_callers INTEGER DEFAULT 0, │ │
|
|
│ │ total_latency_ns BIGINT DEFAULT 0, │ │
|
|
│ │ max_latency_ns BIGINT DEFAULT 0, │ │
|
|
│ │ │ │
|
|
│ │ -- Timestamps │ │
|
|
│ │ first_observed TIMESTAMPTZ NOT NULL DEFAULT NOW(), │ │
|
|
│ │ last_observed TIMESTAMPTZ NOT NULL DEFAULT NOW(), │ │
|
|
│ │ │ │
|
|
│ │ -- Sample data │ │
|
|
│ │ sample_stack JSONB, -- Representative stack trace │ │
|
|
│ │ sample_args JSONB, -- Sample arguments (if captured) │ │
|
|
│ │ │ │
|
|
│ │ -- Constraints │ │
|
|
│ │ CONSTRAINT hot_symbols_unique UNIQUE (image_digest, function_name) │ │
|
|
│ │ ); │ │
|
|
│ │ │ │
|
|
│ │ -- Indexes │ │
|
|
│ │ CREATE INDEX idx_hot_symbols_purl ON signals.hot_symbols(purl); │ │
|
|
│ │ CREATE INDEX idx_hot_symbols_count ON signals.hot_symbols(invocation_count);│ │
|
|
│ │ CREATE INDEX idx_hot_symbols_last ON signals.hot_symbols(last_observed); │ │
|
|
│ │ CREATE INDEX idx_hot_symbols_image ON signals.hot_symbols(image_digest); │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ QUERY EXAMPLES │ │
|
|
│ │ │ │
|
|
│ │ -- Is vulnerable function observed at runtime? │ │
|
|
│ │ SELECT EXISTS ( │ │
|
|
│ │ SELECT 1 FROM signals.hot_symbols │ │
|
|
│ │ WHERE image_digest = $1 │ │
|
|
│ │ AND purl = $2 │ │
|
|
│ │ AND function_name = $3 │ │
|
|
│ │ AND invocation_count > 0 │ │
|
|
│ │ ); │ │
|
|
│ │ │ │
|
|
│ │ -- Get all observed functions for a vulnerable package │ │
|
|
│ │ SELECT function_name, invocation_count, last_observed, sample_stack │ │
|
|
│ │ FROM signals.hot_symbols │ │
|
|
│ │ WHERE image_digest = $1 AND purl = $2 │ │
|
|
│ │ ORDER BY invocation_count DESC; │ │
|
|
│ │ │ │
|
|
│ │ -- Hot path analysis (most called functions) │ │
|
|
│ │ SELECT purl, function_name, SUM(invocation_count) as total_calls │ │
|
|
│ │ FROM signals.hot_symbols │ │
|
|
│ │ WHERE image_digest = $1 │ │
|
|
│ │ GROUP BY purl, function_name │ │
|
|
│ │ ORDER BY total_calls DESC │ │
|
|
│ │ LIMIT 100; │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Runtime Evidence Integration
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ RUNTIME EVIDENCE → POLICY ENGINE │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ REACHABILITY STATE MAPPING │ │
|
|
│ │ │ │
|
|
│ │ Runtime Evidence → Reachability State │ │
|
|
│ │ ───────────────────────────────────────────────────────────────────────── │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Function observed at runtime → DynamicReachable │ │ │
|
|
│ │ │ (invocation_count > 0) (confidence: 0.90) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Function observed + exploit path → LiveExploitPath │ │ │
|
|
│ │ │ (confirmed vulnerable flow) (confidence: 1.00) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Package imported but function → PotentiallyReachable │ │ │
|
|
│ │ │ not observed (long window) (confidence: 0.50) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ No runtime observation → (defer to static analysis) │ │ │
|
|
│ │ │ (posture = None) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ CONFIDENCE FACTOR CALCULATION │ │
|
|
│ │ │ │
|
|
│ │ The Runtime factor (RTS) in confidence scoring: │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Scenario │ RTS Score │ Weight: 0.25 │ │ │
|
|
│ │ │ ──────────────────────────────────┼───────────┼───────────────── │ │ │
|
|
│ │ │ High frequency observation │ 1.00 │ Strong evidence │ │ │
|
|
│ │ │ (invocation_count > 1000/day) │ │ │ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ │ Moderate observation │ 0.80 │ Confirmed used │ │ │
|
|
│ │ │ (invocation_count > 0) │ │ │ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ │ No observation (neutral) │ 0.50 │ Inconclusive │ │ │
|
|
│ │ │ (posture active, no calls) │ │ │ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ │ No observation (long window) │ 0.20 │ Likely unused │ │ │
|
|
│ │ │ (>30 days, no calls) │ │ │ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ │ No runtime posture │ 0.50 │ Cannot determine │ │ │
|
|
│ │ │ (eBPF not available) │ │ │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ EVIDENCE CHAIN │ │
|
|
│ │ │ │
|
|
│ │ When runtime observation is available: │ │
|
|
│ │ │ │
|
|
│ │ Evidence { │ │
|
|
│ │ source: "signals/hot_symbols", │ │
|
|
│ │ evidence_type: "runtime_observation", │ │
|
|
│ │ data: { │ │
|
|
│ │ image_digest: "sha256:abc...", │ │
|
|
│ │ purl: "pkg:npm/lodash@4.17.20", │ │
|
|
│ │ function: "lodash.template", │ │
|
|
│ │ invocation_count: 1247, │ │
|
|
│ │ observation_window: "2024-12-01T00:00:00Z/2024-12-29T00:00:00Z", │ │
|
|
│ │ sample_stack: [ ... ] │ │
|
|
│ │ }, │ │
|
|
│ │ confidence: 0.90, │ │
|
|
│ │ timestamp: "2024-12-29T10:30:00Z" │ │
|
|
│ │ } │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Deployment Considerations
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ DEPLOYMENT CONSIDERATIONS │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ KERNEL REQUIREMENTS │ │
|
|
│ │ │ │
|
|
│ │ Minimum: Linux 5.8+ (BPF_LINK, ring buffer support) │ │
|
|
│ │ Recommended: Linux 5.15+ (BTF, CO-RE) │ │
|
|
│ │ │ │
|
|
│ │ Required kernel config: │ │
|
|
│ │ • CONFIG_BPF=y │ │
|
|
│ │ • CONFIG_BPF_SYSCALL=y │ │
|
|
│ │ • CONFIG_BPF_JIT=y │ │
|
|
│ │ • CONFIG_HAVE_EBPF_JIT=y │ │
|
|
│ │ • CONFIG_DEBUG_INFO_BTF=y (for CO-RE) │ │
|
|
│ │ • CONFIG_UPROBE_EVENTS=y (for uprobes) │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ CONTAINER PRIVILEGES │ │
|
|
│ │ │ │
|
|
│ │ Agent container requires: │ │
|
|
│ │ │ │
|
|
│ │ securityContext: │ │
|
|
│ │ privileged: true # For eBPF loading │ │
|
|
│ │ # OR use capabilities: │ │
|
|
│ │ capabilities: │ │
|
|
│ │ add: │ │
|
|
│ │ - SYS_ADMIN # BPF program loading │ │
|
|
│ │ - SYS_PTRACE # Stack unwinding │ │
|
|
│ │ - SYS_RESOURCE # RLIMIT_MEMLOCK │ │
|
|
│ │ - NET_ADMIN # Network probes │ │
|
|
│ │ - BPF # BPF operations (5.8+) │ │
|
|
│ │ - PERFMON # Performance monitoring (5.8+) │ │
|
|
│ │ │ │
|
|
│ │ Volume mounts: │ │
|
|
│ │ - /sys/kernel/debug (debugfs, for kprobes) │ │
|
|
│ │ - /var/run/docker.sock (container events) │ │
|
|
│ │ - /proc (process info) │ │
|
|
│ │ - /sys/fs/bpf (BPF filesystem, optional) │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ PERFORMANCE IMPACT │ │
|
|
│ │ │ │
|
|
│ │ Overhead by probe type: │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Probe Type │ Latency Added │ CPU Overhead │ Memory │ │ │
|
|
│ │ │ ────────────────┼──────────────────┼──────────────┼──────────────│ │ │
|
|
│ │ │ kprobe │ ~100-500ns │ <0.5% │ ~1MB/probe │ │ │
|
|
│ │ │ tracepoint │ ~50-100ns │ <0.2% │ ~500KB/tp │ │ │
|
|
│ │ │ uprobe │ ~1-5us │ 1-3%* │ ~1MB/probe │ │ │
|
|
│ │ │ USDT │ ~500ns-2us │ <1% │ ~1MB/probe │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ * uprobe overhead depends on call frequency │ │ │
|
|
│ │ └────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ Mitigation strategies: │ │
|
|
│ │ • Selective probe attachment (only observed containers) │ │
|
|
│ │ • In-kernel filtering (reduce userspace events) │ │
|
|
│ │ • Sampling for high-frequency events │ │
|
|
│ │ • Per-container rate limiting │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Tetragon Integration
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ TETRAGON eBPF INTEGRATION │
|
|
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Tetragon provides kernel-level security observability via eBPF TracingPolicies. │
|
|
│ StellaOps integrates Tetragon as a complementary runtime observation source. │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ ARCHITECTURE │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Tetragon Daemon (DaemonSet) │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
|
|
│ │ │ │ kprobe │ │ tracepoint │ │ uprobe │ │ │ │
|
|
│ │ │ │ (syscalls) │ │ (scheduler) │ │ (userspace) │ │ │ │
|
|
│ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │
|
|
│ │ │ │ │ │ │ │ │
|
|
│ │ │ └─────────────────┼─────────────────┘ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ ┌─────────▼─────────┐ │ │ │
|
|
│ │ │ │ TracingPolicy │ │ │ │
|
|
│ │ │ │ CRD Enforcement │ │ │ │
|
|
│ │ │ └─────────┬─────────┘ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ ┌─────────▼─────────┐ │ │ │
|
|
│ │ │ │ Export API │ │ │ │
|
|
│ │ │ │ (gRPC/HTTP) │ │ │ │
|
|
│ │ │ └─────────┬─────────┘ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ └────────────────────────────┼────────────────────────────────────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ┌─────────▼─────────┐ │ │
|
|
│ │ │ StellaOps Agent │ │ │
|
|
│ │ │ (Tetragon) │ │ │
|
|
│ │ └─────────┬─────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ┌────────────────────────────┼───────────────────────────────────────┐ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ ┌─────────────┐ ┌───────▼───────┐ ┌─────────────┐ │ │ │
|
|
│ │ │ │ Privacy │ │ Event │ │ Frame │ │ │ │
|
|
│ │ │ │ Filter │──│ Adapter │──│ Canonicalizer │ │ │
|
|
│ │ │ │ │ │ │ │ │ │ │ │
|
|
│ │ │ └─────────────┘ └───────────────┘ └──────┬──────┘ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ ┌───────────────────────────────────────────┼────────────────┐ │ │ │
|
|
│ │ │ │ │ │ │ │ │
|
|
│ │ │ │ ┌─────────────────┐ ┌───────────────▼────────────┐ │ │ │ │
|
|
│ │ │ │ │ Hot Symbol │ │ Witness │ │ │ │ │
|
|
│ │ │ │ │ Bridge │ │ Bridge │ │ │ │ │
|
|
│ │ │ │ │ │ │ │ │ │ │ │
|
|
│ │ │ │ └────────┬────────┘ └──────────────┬─────────────┘ │ │ │ │
|
|
│ │ │ │ │ │ │ │ │ │
|
|
│ │ │ └───────────┼─────────────────────────────┼──────────────────┘ │ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ └───────────────┼─────────────────────────────┼─────────────────────┘ │ │
|
|
│ │ │ │ │ │
|
|
│ │ ┌─────────▼─────────┐ ┌─────────────▼───────────┐ │ │
|
|
│ │ │ signals.hot_symbols│ │ RuntimeWitnessGenerator │ │ │
|
|
│ │ │ (PostgreSQL) │ │ (Signing Pipeline) │ │ │
|
|
│ │ └────────────────────┘ └─────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ TRACINGPOLICY CONFIGURATION │ │
|
|
│ │ │ │
|
|
│ │ The StellaOps TracingPolicy captures: │ │
|
|
│ │ │ │
|
|
│ │ • Process execution (execve) with full arguments │ │
|
|
│ │ • Network connections (connect, socket) │ │
|
|
│ │ • File operations (open, read, write) │ │
|
|
│ │ • Kernel and user-space stack traces │ │
|
|
│ │ │ │
|
|
│ │ Namespace selectors: stella-ops-*, application namespaces │ │
|
|
│ │ Pod selectors: Via labels (stellaops.io/observe=true) │ │
|
|
│ │ │ │
|
|
│ │ Policy file: devops/manifests/tetragon/stella-ops-tracing-policy.yaml │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ COMPONENT RESPONSIBILITIES │ │
|
|
│ │ │ │
|
|
│ │ TetragonAgentCapability: │ │
|
|
│ │ • Connects to Tetragon Export API (gRPC) │ │
|
|
│ │ • Implements IAgentCapability interface │ │
|
|
│ │ • Supports start/stop collection, status, flush tasks │ │
|
|
│ │ • Health checks via Tetragon health endpoint │ │
|
|
│ │ │ │
|
|
│ │ TetragonEventAdapter: │ │
|
|
│ │ • Converts TetragonEvent to RuntimeCallEvent format │ │
|
|
│ │ • Maps stack frames to canonical symbols │ │
|
|
│ │ • Extracts process/container context │ │
|
|
│ │ │ │
|
|
│ │ TetragonFrameCanonicalizer: │ │
|
|
│ │ • Resolves Build-ID for binaries │ │
|
|
│ │ • Demangles C++, Rust, Go symbol names │ │
|
|
│ │ • Computes function IDs matching static analysis │ │
|
|
│ │ • Format: buildid:function+offset │ │
|
|
│ │ │ │
|
|
│ │ TetragonHotSymbolBridge: │ │
|
|
│ │ • Records observations to hot_symbols index │ │
|
|
│ │ • Time-window aggregation (1-minute windows) │ │
|
|
│ │ • Confidence scoring (0.20-1.00 range) │ │
|
|
│ │ │ │
|
|
│ │ TetragonWitnessBridge: │ │
|
|
│ │ • Buffers observations by claim_id │ │
|
|
│ │ • Emits to RuntimeWitnessGenerator │ │
|
|
│ │ • Implements backpressure via SemaphoreSlim │ │
|
|
│ │ │ │
|
|
│ │ TetragonPrivacyFilter: │ │
|
|
│ │ • Argument redaction (passwords, tokens, PII) │ │
|
|
│ │ • Symbol-ID-only mode for privacy-sensitive envs │ │
|
|
│ │ • Namespace allowlisting │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ TETRAGON vs SIGNALS COMPARISON │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Aspect │ Signals (Native) │ Tetragon Integration │ │ │
|
|
│ │ │ ─────────────────┼──────────────────────┼────────────────────────│ │ │
|
|
│ │ │ Deployment │ Custom eBPF agent │ Standard Tetragon │ │ │
|
|
│ │ │ Configuration │ Code-level │ TracingPolicy CRD │ │ │
|
|
│ │ │ Policy management │ Recompile │ K8s-native (kubectl) │ │ │
|
|
│ │ │ Stack capture │ Custom unwinding │ Built-in │ │ │
|
|
│ │ │ Ecosystem │ StellaOps only │ CNCF, broad adoption │ │ │
|
|
│ │ │ Use case │ Deep integration │ Standard compliance │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ Recommendation: Use Tetragon for Kubernetes environments with compliance │ │
|
|
│ │ requirements. Use native Signals for maximum control and non-K8s estates. │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ PERFORMANCE TARGETS │ │
|
|
│ │ │ │
|
|
│ │ Target KPIs for Tetragon integration: │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ Metric │ Target │ Measurement │ │ │
|
|
│ │ │ ─────────────────────────┼──────────────────┼──────────────────────│ │ │
|
|
│ │ │ CPU overhead │ <5% │ Per monitored pod │ │ │
|
|
│ │ │ Memory overhead (agent) │ <100MB │ Agent container │ │ │
|
|
│ │ │ Capture latency (P95) │ <100ms │ Event to hot_symbols │ │ │
|
|
│ │ │ Throughput │ >10,000 events/s │ Per agent instance │ │ │
|
|
│ │ │ Privacy filter overhead │ <10% │ Compared to baseline │ │ │
|
|
│ │ │ Frame canonicalization │ <10ms per frame │ With symbol resolve │ │ │
|
|
│ │ │ Function ID computation │ <0.1ms per call │ Hash + format │ │ │
|
|
│ │ │ Demangling throughput │ >100,000 sym/s │ Mixed C++/Rust/Go │ │ │
|
|
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ Benchmarks: src/RuntimeInstrumentation/StellaOps.RuntimeInstrumentation. │ │
|
|
│ │ Tetragon.Tests/Benchmarks/TetragonPerformanceBenchmarks.cs │ │
|
|
│ │ │ │
|
|
│ └──────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Tetragon Deployment Guide
|
|
|
|
### Prerequisites
|
|
|
|
1. **Kubernetes cluster** with Linux nodes (kernel 5.8+)
|
|
2. **Tetragon installed** via Helm or operator
|
|
3. **StellaOps control plane** deployed
|
|
|
|
### Installation Steps
|
|
|
|
```bash
|
|
# 1. Install Tetragon (if not already installed)
|
|
helm repo add cilium https://helm.cilium.io
|
|
helm install tetragon cilium/tetragon -n kube-system
|
|
|
|
# 2. Apply StellaOps TracingPolicy
|
|
kubectl apply -f devops/manifests/tetragon/stella-ops-tracing-policy.yaml
|
|
|
|
# 3. Deploy StellaOps Tetragon Agent
|
|
kubectl apply -f devops/manifests/tetragon/stella-ops-tetragon-agent-daemonset.yaml
|
|
|
|
# 4. Verify deployment
|
|
kubectl get pods -n stella-ops -l app=stella-ops-tetragon-agent
|
|
kubectl logs -n stella-ops -l app=stella-ops-tetragon-agent --tail=50
|
|
```
|
|
|
|
### Configuration
|
|
|
|
The Tetragon agent is configured via ConfigMap:
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: stella-ops-tetragon-config
|
|
namespace: stella-ops
|
|
data:
|
|
config.yaml: |
|
|
tetragon:
|
|
address: "tetragon.kube-system.svc:54321"
|
|
connectionTimeout: 30s
|
|
|
|
hotSymbols:
|
|
aggregationWindowSeconds: 60
|
|
minConfidenceThreshold: 0.2
|
|
flushIntervalSeconds: 30
|
|
|
|
privacy:
|
|
redactArguments: true
|
|
useDefaultRedactionPatterns: true
|
|
symbolIdOnlyMode: false
|
|
allowedNamespaces:
|
|
- stella-ops-workloads
|
|
- default
|
|
```
|
|
|
|
### Monitoring
|
|
|
|
The agent exposes Prometheus metrics at `:8080/metrics`:
|
|
|
|
- `tetragon_events_total` - Total events received
|
|
- `tetragon_events_filtered` - Events dropped by privacy filter
|
|
- `tetragon_hotsymbols_flushed` - Hot symbols written to DB
|
|
- `tetragon_witness_generated` - Runtime witnesses generated
|
|
- `tetragon_latency_seconds` - Event processing latency histogram
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- [Policy Engine Data Pipeline](policy-engine-data-pipeline.md) - How runtime feeds policy
|
|
- [Reachability Drift Alert Flow](../../flows/19-reachability-drift-alert-flow.md) - Runtime-triggered alerts
|
|
- [Signals Module Architecture](../../modules/signals/architecture.md) - Signals module dossier
|
|
- [Zastava Architecture](../../modules/zastava/architecture.md) - Container observer dossier
|
|
- [Tetragon Integration Sprint](../../implplan/SPRINT_20260118_019_Infra_tetragon_integration.md) - Implementation details
|