Skip to content
OCSF v1.3 native · MITRE ATT&CK on every detection

Runtime security that watches what your workloads actually do

Falak Neo attaches eBPF programs to the kernel paths that matter — exec, file open, socket connect, DNS, bpf() — and turns what it sees into OCSF events before anything leaves the host. No log parsing, no sidecars, no guessing what a container did from its stdout.

Apache-2.0 sensor and core · Self-host or run it as SaaS · No credit card for the trial

falak events tail --class 1007 --severity high
{
  "class_uid": 1007, "class_name": "Process Activity",
  "type_uid": 100701, "severity_id": 5,
  "process": {
    "name": "memfd:payload", "pid": 41290,
    "cmd_line": "/proc/self/fd/3 --stage2"
  },
  "exec_from_memfd": true,
  "device": { "k8s": { "namespace": "payments", "pod_name": "ledger-writer-7f9c…" } },
  "finding_info": { "attacks": [{ "uid": "T1620", "name": "Reflective Code Loading" }] }
}

< 1%

sensor CPU on a busy node

~80 MiB

resident memory, steady state

11

OCSF classes emitted

0

detections without an ATT&CK technique

The problem

You cannot defend a workload you can only see from the outside

Most runtime tooling infers behaviour from artefacts the workload chose to emit. That is a reasonable place to start and a terrible place to stop.

Logs describe intent. eBPF records outcome.

An application log says what a developer decided to write down. A kernel probe on sched_process_exec records what actually executed, including the payload that was never meant to leave a trace.

Containers are opaque to everything above them

Runtime, orchestrator and service mesh each see a slice. The kernel sees all of them at once, and it can attribute a syscall to a PID namespace, a cgroup, and therefore to a pod.

Detection without attribution is noise

An alert that cannot say which technique it corresponds to cannot be prioritised, cannot be measured for coverage, and cannot be handed to an on-call engineer at 3am.

Platform

Everything a runtime security programme needs, and nothing it doesn't

Nine capabilities, each of which exists because a real incident was harder than it should have been without it.

Kernel-native collection

CO-RE eBPF programs attached to exec, file open, connect, accept, DNS, bpf() and ptrace. Ring-buffer drained by a Rust userspace that never blocks the kernel path.

OCSF v1.3 on the wire

Events are valid OCSF documents before they leave the host. protojson output is the wire format — there is no vendor schema and no translation layer to drift.

ATT&CK is mandatory, not decorative

A detection without at least one mapped technique is rejected by the pipeline. That is what makes the coverage matrix trustworthy instead of aspirational.

Kubernetes context on every event

Cluster, namespace, pod, workload kind, service account and image digest resolved from the CRI and the API server, attached to the event rather than joined later.

Attack graph, not an alert list

Process, container, pod, identity and external address as nodes; spawned, connected-to, mounted and authenticated-as as edges. Read the path, not the pile.

Hunting on the same fields

The hunt query language addresses the exact OCSF attribute paths the sensor emits, so a hunt that finds something is promoted to a rule without re-expressing it.

Response the sensor can refuse

Kill, isolate, quarantine and stop-container are signed by core with an expiry. An unsigned or expired action is refused at the sensor — the console can request, never execute.

Policy as a signed artefact

Probes, filters, sampling and fast-path rules compile to a signed SensorConfig. Sensors report the generation they applied, so convergence is measured rather than assumed.

Multi-tenant by construction

Tenancy is derived from the authenticated mTLS identity, never asserted by a sensor. Core overwrites any tenant a client claims before the event reaches storage.

Architecture

Sensor → core → console. Three moving parts.

There is no collector tier, no relay, and no log shipper to operate. Every architectural decision below was made to reduce the number of things that can be misconfigured between a syscall and an alert.

Falak Neo architectureA Rust and eBPF sensor runs on every Linux host and Kubernetes node, attaching probes to process exec, file open, socket connect, DNS and kernel calls. It constructs OCSF v1.3 events and streams them over mutually authenticated gRPC directly to falak-neo-core, with no relay tier. Core validates the schema, enriches events with Kubernetes and cloud context, evaluates detection rules mapped to MITRE ATT&CK, writes events to ClickHouse and application state to PostgreSQL, and serves a REST and JSON API to the analyst console. Core also pushes signed sensor configuration and signed response actions back down to each sensor.YOUR INFRASTRUCTURELinux kerneleBPF programs, CO-RE, BTFsched_process_execfile_open (LSM)sys_enter_connectbpf() / ptrace / dnsfalak-neo-minionRust · ring buffer drainOCSF v1.3 constructionbatch · zstd · disk spool< 1% CPU, ~80 MiB RSSPods · containers · systemd unitsobserved, never instrumentedmTLS gRPCEventBatch→ BatchAckcontrolsigned SensorConfigsigned actionsFALAK-NEO-CORE (Go)Ingestschema validation · dedup · backpressureEnrichmentK8s informer · cloud metadata · intelDetectionsigma + behavioural · ATT&CK requiredControl planeenrollment · policy · signed actionsClickHouseOCSF eventstenant-partitionedPostgreSQLtenants · agentstriage · policyREST / JSONtenant-scopedCONSUMERSAnalyst consolealert triageattack graphthreat huntingfleet + policySIEM / SOARSplunk · ElasticPagerDuty · JiraOCSF NDJSON exportData lakeS3 · OCSF parquetyour own API clients
One sensor per host. One stream per sensor. No collector tier, no relay, no log shipper to babysit — the sensor speaks to core directly over mutually authenticated gRPC, and core is the only component that ever holds a tenant's data.

falak-neo-minion

Rust · eBPF · one per host

  • CO-RE programs, no per-kernel rebuild
  • Sensitive-path classification in-kernel
  • Disk spool survives a core outage
  • Reports its own probe attachment state

falak-neo-core

Go monolith · ClickHouse + PostgreSQL

  • Schema validation and idempotent dedup
  • K8s and cloud enrichment at ingest
  • Sigma plus behavioural correlation
  • Signs config and response actions

Analyst console

Next.js · multi-tenant

  • Virtualized alert feed, six figures of findings
  • Timeline, process tree and attack graph
  • ATT&CK coverage matrix from live content
  • Sensor policy editor with drift tracking

Standards

Built on schemas your team already argues in

Two open standards do the heavy lifting: OCSF for what happened, ATT&CK for what it means. Neither is a badge on a slide — both are enforced by the pipeline.

OCSF v1.3 — the classes we actually emit

Falak implements a deliberate subset. Adding a class requires a probe that can populate it with high fidelity and a storage projection that can hold it — not a mapping table.

1001File System Activityopen, write, rename, unlink, chmod
1003Kernel Activitybpf(), ptrace, kallsyms, capabilities
1005Module ActivityLKM and shared library loads
1007Process Activityexec, exit, inject, setuid
2004Detection Findingemitted by core, never by a sensor
3002AuthenticationSSH, PAM, service tickets
4001Network Activityconnect, accept, traffic volume, TLS
4003DNS Activityqueries and answers, parsed on the socket path
5001Device Inventory Infopackages, services, asset sync
5002Device Config StateCIS benchmark and posture results
6003API Activitycloud control-plane audit ingestion
990001Container Lifecyclethe one documented Falak extension

type_uid = class_uid × 100 + activity_id
// computed, never guessed — enforced at ingest

MITRE ATT&CK — coverage you can audit

Every finding carries at least one technique. The console renders a Navigator-style matrix scoped to the techniques a Linux and Kubernetes sensor can actually observe — techniques it structurally cannot see are absent rather than shown as permanent gaps.

Initial AccessExecutionPersistencePrivilege EscalationDefense EvasionCredential AccessDiscoveryLateral MovementCollectionCommand & ControlExfiltrationImpact

Sub-technique granularity where the sensor supports it: T1059.004 Unix Shell, T1548.001 Setuid and Setgid, T1003.008 /etc/shadow, T1071.004 DNS, T1611 Escape to Host.

How a detection happens

From syscall to signed response, in one worked example

Fileless execution from a memory file descriptor — the canonical Linux evasion primitive, and a good test of whether a runtime tool is watching the kernel or reading a log.

01

The sensor sees an exec whose inode has no path

sched_process_exec fires. The resolved executable is an anonymous memfd, so the sensor sets exec_from_memfd on a 1007 Process Activity event and stamps the container and pod context from the cgroup.

class_uid: 1007
activity_id: 1        # Launch
exec_from_memfd: true
device.k8s.pod_name: "ledger-writer-7f9c…"
02

Core correlates it with what happened around it

A shell exec two minutes earlier, a connect() to an unfamiliar ASN eight seconds later. Core links them by process ancestry, not by timestamp proximity alone.

correlation_uid: "4f2c…"
related_events_uids: [ 3 events ]
kill_chain: [ "Execution", "Defense Evasion" ]
03

The finding is emitted with its technique attached

A 2004 Detection Finding with T1620 Reflective Code Loading and T1059.004 Unix Shell, a risk score, and the evidence event ids. Without a technique, it would not have been emitted at all.

class_uid: 2004
finding_info.attacks[0].uid: "T1620"
risk_score: 88
confidence: "High"
04

The analyst gets a path, not a row

Timeline, full process ancestry with the memfd flag highlighted, the entity graph, and a signed kill-process action that the sensor will verify before it runs.

action.type: "KillProcess"
action.signature: <ed25519>
action.expires_at: +120s

In practice

What teams actually catch with it

Container escape

A privileged pod mounts the node root and execs through it. Falak correlates the ContainerLifecycle mount set with the subsequent exec's device and mount point — the single-step escape, caught at the step.

T1611 Escape to Host

Credential theft

/etc/shadow, projected service-account tokens, ~/.aws/credentials and /proc/<pid>/mem, classified in-kernel so the detection does not require shipping the entire file-open firehose.

T1003 · T1552

Cloud credential pivot

IMDS reached from inside a workload container, followed by a control-plane call from an unfamiliar address. Runtime and control plane in one timeline, not two consoles.

T1552.007 · T1078.004

Cryptomining and C2

Sustained all-core CPU with Stratum-family egress and miner argv, or high-entropy DNS labels under one parent zone. Scored over a window so a single burst does not page anyone.

T1496 · T1071.004

Put a sensor on one node and see what it finds

A single DaemonSet, one enrollment token, and roughly five minutes. Most teams have a finding worth investigating inside the first hour — usually something they already had, and had never seen.

Prefer to self-host? The sensor and core are Apache-2.0. Read the architecture guide.