Falco security monitoring with Edera
Edera integrates with Falco, the cloud-native runtime security project, to provide deep observability into protected zones. Using eBPF-based syscall monitoring, Falco can detect threats, policy violations, and suspicious activity as workloads run inside Edera’s hypervisor-isolated zones. While Edera mitigates container escapes and access to shared host resources, security observability is a crucial aspect of defense-in-depth.
This guide shows you how to configure the Edera plugin for Falco and start monitoring zone activity with custom security rules.
What you’ll learn
- How the Edera Falco plugin works
- How to configure Falco to monitor Edera zones
- How to write rules that trigger on zone activity
- How to verify events are streaming from your zones
Prerequisites
Before you begin, make sure you have:
- Edera Protect installed and the daemon running (
/var/lib/edera/protect/daemon.socketavailable) - Falco installed (version 0.41.0 or later recommended) - either:
- Directly on nodes via package manager (yum/apt), OR
- Via Helm charts in your Kubernetes cluster
- Root or sudo access (for node-based installation) OR Helm access (for Kubernetes installation)
- At least one Edera zone you can launch for testing
How it works
The Edera Falco plugin bridges Falco’s runtime security engine with Edera’s zone isolation. Here’s the architecture:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Host (Dom0) │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Falco (runtime security engine) │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Edera Plugin (libedera_falco_plugin.so) │ │ │
│ │ │ │ │ │
│ │ │ • Zone discovery & management │ │ │
│ │ │ • Thread/FD snapshot tables (per zone) │ │ │
│ │ │ • Event enrichment & context tracking │ │ │
│ │ └─────────────────────┬──────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ (3) Connect to daemon socket │ │
│ │ ▼ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────▼────────────────────────────────────────────┐ │
│ │ Edera Daemon │ │
│ │ (/var/lib/edera/protect/daemon.socket) │ │
│ │ │ │
│ │ • Zone lifecycle management │ │
│ │ • IDM channel host │ │
│ │ • Hypervisor interface (Xen) │ │
│ └─────────────────────┬──────────────────┬────────────────────────────┘ │
│ │ │ │
│ │ (4) Query zones │ (5) Monitor syscalls (IDM msg) │
│ │ │ │
└────────────────────────┼──────────────────┼─────────────────────────────────┘
│ │
╪══════════════════╪
│ Hypervisor (Xen) │
│ • Memory/CPU │
│ • Event channels│
╪══════════════════╪
│ │
▼ ▼
┌────────────────────────────────────────────────────────────────────────────┐
│ Zone - MicroVM │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ Zone kernel (Linux PV/PVH) │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ libscap_rs (loaded on demand by monitor syscalls message) │ │ │
│ │ │ │ │ │
│ │ │ • Installs eBPF programs in zone kernel context │ │ │
│ │ │ • Snapshots threads & file descriptors │ │ │
│ │ │ • Harvests syscall events via eBPF │ │ │
│ │ └────────────────┬──────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ (6) Syscall events │ │
│ │ │ │ │
│ └───────────────────┼────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────▼──────────────────────────────────────────────┐ │
│ │ Styrolite (container runtime) │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ Workload (OCI container) │ │ │
│ │ │ │ │ │
│ │ │ • Application processes │ │ │
│ │ │ • open(), read(), write(), execve(), connect()... │ │ │
│ │ │ │ │ │
│ │ │ (All syscalls monitored by eBPF probes above) │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ (7) Stream events over IDM │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ IDM Client (protobuf over shared memory + event channels) │ │
│ └─────────────────────────┬────────────────────────────────────────┘ │
└────────────────────────────┼───────────────────────────────────────────────┘
│
│ (8) Enriched event stream
│
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ Back to Edera Plugin in Host │
│ │
│ • Receives syscall events over IDM │
│ • Updates thread/FD tables with new state │
│ • Enriches events with contextual data (process tree, FD mappings) │
│ • Exposes enriched events to Falco rules engine │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Falco Rules Engine │ │
│ │ │ │
│ │ • Evaluates security rules against event stream │ │
│ │ • Matches conditions (file paths, processes, syscalls) │ │
│ │ • Generates alerts on rule violations │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ Output: Security alerts, logs, SIEM integration │
└────────────────────────────────────────────────────────────────────────────┘Event flow
- Plugin loads - Falco loads
/var/lib/edera/protect/falco/libedera_falco_plugin.soat startup - Zone discovery - The plugin connects to
/var/lib/edera/protect/daemon.socketand queries for running zones - eBPF instrumentation - For each zone, the plugin sends a “monitor syscalls” message over Edera’s IDM (inter-domain messaging), which:
- Instructs the zone binary to load
libscap_rs - Installs eBPF programs inside the zone’s kernel context. These eBPF programs are the same ones used by upstream Falco on the host, and support the same kinds of hooks and syscalls.
- Snapshots all threads and file descriptors currently running in the zone
- Begins streaming syscall events back to the host over IDM
- Instructs the zone binary to load
- Event enrichment - The plugin maintains internal thread and FD tables for each zone, using snapshot data and live events to enrich context
- Rule evaluation - Falco evaluates your security rules against the enriched event stream
- Cleanup - When zones terminate, their monitoring tables are automatically purged
Note
If a CPU hotplug event is detected inside a zone, the plugin disconnects and reconnects to avoid stale cache data. This is similar to Falco’s behavior on bare metal, but doesn’t require restarting the Falco agent.
Configuration
The configuration steps differ based on your Falco installation method. Choose the section that matches your setup:
- Node-based installation - Falco installed directly on nodes via yum/apt
- Helm-based installation - Falco deployed as a Kubernetes DaemonSet
Node-based installation
Follow these steps if you installed Falco directly on your nodes using a package manager (yum, apt, etc.).
Step 1: Configure the Edera plugin
Edit /etc/falco/falco.yaml and add the Edera plugin to the plugins section:
plugins:
- name: container
library_path: libcontainer.so
init_config:
label_max_len: 100
with_size: false
- name: edera
library_path: /var/lib/edera/protect/falco/libedera_falco_plugin.so
init_config:
mirror_host_syscalls: trueThis tells Falco where to find the Edera plugin shared library.
Note
mirror_host_syscalls: true means the plugin will configure zones to only monitor the specific set of syscalls that Falco is already monitoring on the host.
If this value is unset, or false, zones will monitor and emit events for a default set of syscalls instead.
Step 2: Enable the Edera plugin
Create /etc/falco/config.d/falco.edera_plugin.yaml to explicitly load the Edera plugin:
load_plugins: [edera]Step 3: Add a detection rule
Edit /etc/falco/falco_rules.yaml (or create a custom rules file) and add a rule for Edera events. Here’s a simple example that logs all zone activity:
- macro: open_read_edera
condition: (evt.pluginname == "edera")
- rule: Edera Events
desc: >
Logs every syscall event from every running Edera zone, with no filtering.
Useful for testing and understanding what events are available.
source: edera_zone
output: >
Edera Event | time=%evt.time zone_id=%edera.zone.id evt.type=%evt.type
syscall.type=%syscall.type evt.category=%evt.category evt.dir=%evt.dir
proc.exe=%proc.exe evt.args=%evt.args is_open=%evt.type.is[open]
priority: WARNING
tags: [edera_zone, filesystem]
condition: >
open_read_edera Tip
This rule uses the edera_zone source and checks evt.pluginname == "edera" to filter events. You can refine the condition field to focus on specific syscalls, processes, or file paths.
Step 4: Restart Falco
Restart the Falco service to apply your configuration changes:
sudo systemctl restart falcoSkip to Step 4: Launch a zone to continue.
Helm-based installation
Follow these steps if you installed Falco via Helm charts in your Kubernetes cluster.
Note
Security considerations: Deploying privileged node-level security tools like Falco via Kubernetes and Helm requires mounting sensitive host paths (daemon sockets, plugin binaries) into pods. While this approach is widely used and supported, it introduces additional attack surface compared to installing Falco directly on nodes via package managers.
For production environments with strict security requirements, we recommend installing Falco directly on nodes using the node-based installation method. This provides better isolation and follows the principle of least privilege.
If you choose the Helm-based approach, ensure you:
- Restrict access to the Falco namespace using Kubernetes RBAC
- Audit the Falco Helm chart and container images before deployment
- Monitor Falco pod activity and limit network access where possible
- Follow Falco’s security best practices for production deployments
Step 1: Create Helm values file
When Falco runs as a Kubernetes DaemonSet, the configuration must be provided through Helm values rather than editing files on the node. The Falco pods need to mount the Edera plugin and daemon socket from the host.
Create a file called falco-edera-values.yaml:
# Mount Edera plugin and daemon socket from host into Falco pods
mounts:
volumes:
- name: edera-plugin
hostPath:
path: /var/lib/edera/protect/falco
- name: edera-daemon-socket
hostPath:
path: /var/lib/edera/protect
volumeMounts:
- name: edera-plugin
mountPath: /var/lib/edera/protect/falco
readOnly: true
- name: edera-daemon-socket
mountPath: /var/lib/edera/protect
readOnly: false
# Configure the Edera plugin
falco:
plugins:
- name: edera
library_path: /var/lib/edera/protect/falco/libedera_falco_plugin.so
init_config:
mirror_host_syscalls: true
load_plugins: [edera]
# Add custom Edera detection rules
customRules:
edera-rules.yaml: |-
- macro: open_read_edera
condition: (evt.pluginname == "edera")
- rule: Edera Events
desc: >
Logs every syscall event from every running Edera zone, with no filtering.
Useful for testing and understanding what events are available.
source: edera_zone
output: >
Edera Event | time=%evt.time zone_id=%edera.zone.id evt.type=%evt.type
syscall.type=%syscall.type evt.category=%evt.category evt.dir=%evt.dir
proc.exe=%proc.exe evt.args=%evt.args is_open=%evt.type.is[open]
priority: WARNING
tags: [edera_zone, filesystem]
condition: >
open_read_edera
- rule: Edera Sensitive File Read
desc: Detects when a process in an Edera zone reads files in /etc
source: edera_zone
output: >
Sensitive file read in zone | zone_id=%edera.zone.id proc=%proc.exe
file=%fd.name
priority: WARNING
condition: >
evt.pluginname == "edera" and
evt.type == open and
fd.name startswith /etc
- rule: Edera Process Execution
desc: Logs all process executions inside Edera zones
source: edera_zone
output: >
Process executed in zone | zone_id=%edera.zone.id proc=%proc.exe
cmdline=%proc.cmdline
priority: NOTICE
condition: >
evt.pluginname == "edera" and
evt.type == execve Note
mirror_host_syscalls: true means the plugin will configure zones to only monitor the specific set of syscalls that Falco is already monitoring on the host.
If this value is unset, or false, zones will monitor and emit events for a default set of syscalls instead.
Step 2: Upgrade Falco with the new configuration
Apply the configuration by upgrading your Falco Helm release:
helm upgrade falco falcosecurity/falco \
-n falco \
-f falco-edera-values.yamlThis will:
- Mount the Edera plugin library and daemon socket into Falco pods
- Configure the Edera plugin
- Add custom detection rules for monitoring zone activity
Step 3: Verify Falco pods are running
Check that the Falco pods have restarted and are running:
kubectl get pods -n falcoYou can check the Falco logs to see if the plugin loaded successfully:
kubectl logs -n falco -l app.kubernetes.io/name=falco | grep -i ederaYou should see messages about the Edera plugin loading and waiting for zones.
Step 4: Launch a zone
Start a test zone with a nginx workload so you have something to monitor:
sudo protect zone launch \
--name nginx \
--kernel-verbose \
--kernel ghcr.io/edera-dev/zone-kernel:6.16
sudo protect workload launch \
--zone nginx \
--name nginx \
docker.io/library/nginx:alpineStep 5: Stream Falco events
The method to view Falco events depends on your installation type:
For node-based installations
Run Falco in the foreground with debug logging to see events as they arrive:
sudo falco -o "log_level=debug"For Helm-based installations
Stream the logs from a Falco pod:
kubectl logs -n falco -l app.kubernetes.io/name=falco -fTo see debug-level logging, you can enable it in your Helm values:
falco:
log_level: debugThen upgrade the release:
helm upgrade falco falcosecurity/falco \
-n falco \
-f falco-edera-values.yamlExpected output
You should see Falco discover your zone, install eBPF probes, and begin streaming events:
Thu Oct 30 20:30:29 2025: [libs]: edera: [INFO] waiting for zones
Thu Oct 30 20:30:39 2025: [libs]: edera: [INFO] got zone ZoneMetadata { domid: 3, uuid: 30782e65-f18d-4d5e-a37b-2acbdd67418d }
Thu Oct 30 20:30:39 2025: [libs]: edera: [INFO] pushing handle for zone 30782e65-f18d-4d5e-a37b-2acbdd67418d
Thu Oct 30 20:30:39 2025: [libs]: edera: [INFO] starting zone event pump for zone 30782e65-f18d-4d5e-a37b-2acbdd67418d
Thu Oct 30 20:30:39 2025: [libs]: edera: [INFO] Listening for kernel events from zone 30782e65-f18d-4d5e-a37b-2acbdd67418d
20:30:45.734123070: Warning EDERA Event | time=20:30:45.734123070 zone_id=30782e65-f18d-4d5e-a37b-2acbdd67418d evt.type=open syscall.type=open evt.category=EC_SYSCALL evt.dir=< proc.exe=zone evt.args=| PT_FD 368| PT_FSPATH /proc/stat| PT_FLAGS32 0x00000801| PT_UINT32 0| PT_UINT32 20| PT_UINT64 4026532094| is_open=true
20:30:45.734187106: Warning EDERA Event | time=20:30:45.734187106 zone_id=30782e65-f18d-4d5e-a37b-2acbdd67418d evt.type=close syscall.type=close evt.category=EC_SYSCALL evt.dir=> proc.exe=zone evt.args=| PT_FD 368| is_open=falseEach event includes:
- zone_id - The UUID of the zone that generated the event
- evt.type - The syscall type (open, close, execve, etc.)
- proc.exe - The process that made the syscall
- evt.args - Parsed syscall arguments (file paths, FDs, flags, etc.)
Available event fields
The Edera plugin exposes the same queryable fields on its zone events that Falco’s host events do.
Currently this includes all members of the following field classes
with the following exceptions:
- Due to Falco plugin API limitations, fields that under Falco support multiple forms of argument-based indexing only support numeric indexes in the Edera plugin context (ex:
evt.arg[0]is supported,evt.arg.fdis not). - Due to Falco plugin API limitations,
evt.rawargandevt.rawresare not supported (useevt.argandevt.resinstead) thread.cpu,thread.cpu.user, andthread.cpu.systemare not supported at this time.fd.containernameandfd.containerdirectoryare not supported at this time.fd.name_changedis not supported at this time.- The
userfield class is not supported at this time. - The
groupfield class is not supported at this time.
Support for the container field class is planned.
The Edera plugin additionally exposes the following new, plugin-specific fields on its events:
| Field | Description |
|---|---|
edera.zone.id | UUID of the zone that generated the event |
As with standard Falco host events, some field classes come from raw event data; others are enriched using the plugin’s internal thread and FD snapshot tables.
Example rules
Detect file access in /etc
- [ ] rule: Edera Sensitive File Read
desc: Detects when a process in an Edera zone reads files in /etc
source: edera_zone
output: >
Sensitive file read in zone | zone_id=%edera.zone.id proc=%proc.exe
file=%fd.name user=%user.name
priority: WARNING
condition: >
evt.pluginname == "edera" and
evt.type == open and
fd.name startswith /etc Detect process execution
- rule: Edera Process Execution
desc: Logs all process executions inside Edera zones
source: edera_zone
output: >
Process executed in zone | zone_id=%edera.zone.id proc=%proc.exe
cmdline=%proc.cmdline user=%user.name
priority: NOTICE
condition: >
evt.pluginname == "edera" and
evt.type == execve Detect network connections
- rule: Edera Outbound Connection
desc: Detects outbound network connections from Edera zones
source: edera_zone
output: >
Outbound connection from zone | zone_id=%edera.zone.id proc=%proc.exe
dest=%fd.rip:%fd.rport proto=%fd.l4proto
priority: INFO
condition: >
evt.pluginname == "edera" and
evt.type == connect and
fd.type == ipv4 Troubleshooting
No events appearing
Node-based troubleshooting
Check the Falco logs for errors related to the Edera plugin:
sudo falco -o "log_level=debug" 2>&1 | grep -i ederaVerify the socket exists:
ls -l /var/lib/edera/protect/daemon.socketConfirm zones are running:
sudo protect zone listHelm-based troubleshooting
Check the Falco pod logs for errors related to the Edera plugin:
kubectl logs -n falco -l app.kubernetes.io/name=falco -c falco | grep -i ederaVerify the socket and plugin are mounted in the Falco pod:
# Get the Falco pod name
FALCO_POD=$(kubectl get pods -n falco -l app.kubernetes.io/name=falco -o jsonpath='{.items[0].metadata.name}')
# Check if daemon socket is mounted
kubectl exec -n falco $FALCO_POD -c falco -- ls -l /var/lib/edera/protect/daemon.socket
# Check if plugin library exists
kubectl exec -n falco $FALCO_POD -c falco -- ls -l /var/lib/edera/protect/falco/libedera_falco_plugin.soConfirm zones are running on the node (SSH to node or use kubectl debug):
# Using kubectl debug
kubectl debug node/<node-name> -it --image=busybox -- chroot /host protect zone listVerify the Helm values were applied:
helm get values falco -n falcoPlugin fails to load
Node-based plugin loading
Check plugin file permissions:
ls -l /var/lib/edera/protect/falco/libedera_falco_plugin.soThe file should be readable by the user running Falco (typically root).
Verify Falco version compatibility:
falco --versionThe Edera plugin requires Falco 0.41.0 or later.
Helm-based plugin loading
Check if the hostPath volumes are correctly mounted. The plugin and socket must exist on the host node at:
/var/lib/edera/protect/falco/libedera_falco_plugin.so/var/lib/edera/protect/daemon.socket
Verify these exist on your nodes using kubectl debug:
kubectl debug node/<node-name> -it --image=busybox -- ls -l /host/var/lib/edera/protect/Check Falco pod events for mounting errors:
kubectl describe pods -n falco -l app.kubernetes.io/name=falcoLook for errors related to volume mounts or plugin loading.
Verify the Falco image version:
kubectl get pods -n falco -l app.kubernetes.io/name=falco -o jsonpath='{.items[0].spec.containers[0].image}'The Edera plugin requires Falco 0.41.0 or later.
Plugin keeps reconnecting to zones
If you see the plugin repeatedly logging messages like this every few seconds:
[libs]: edera: [INFO] mirroring syscalls enabled on host
[libs]: edera: [INFO] read 69 enabled syscalls
[libs]: edera: [INFO] Listening for kernel events from zone <UUID>This indicates the connection to the zone is being re-established repeatedly. This can happen if:
The event stream connection is unstable - Check the Edera daemon logs for any errors or connection issues:
# For node-based installations
sudo journalctl -u edera-protect -f
# For Helm-based installations (check node logs)
kubectl debug node/<node-name> -it --image=busybox -- chroot /host journalctl -u edera-protect -n 50The zone is restarting or having issues - Verify the zone/workload is running stably:
# Check pod status
kubectl get pod <pod-name>
# Check pod events
kubectl describe pod <pod-name>If the plugin continuously reconnects and no events appear, this may indicate an issue with the event streaming mechanism. Contact Edera support with:
- Falco logs showing the reconnection pattern
- Edera daemon logs from the affected node
- Zone/workload information
Events stop streaming after CPU hotplug
This is expected behavior, and similar to Falco’s behavior when hostside CPU hotplug events are detected. The plugin will automatically disconnect and reconnect to the zone where the hotplug event was detected to invalidate the zone’s thread cache, and then resume processing events. You should see log messages indicating the reconnection.
Next steps
- Write custom rules - Tailor Falco rules to your security policies and compliance requirements
- Integrate with SIEM - Forward Falco alerts to your SIEM or logging platform (for example, Splunk, Elasticsearch)
- Explore Falco outputs - Configure Falco to send alerts to Slack, PagerDuty, or other notification channels
- Review Falco docs - Learn more about Falco rules syntax and best practices
Summary
You’ve successfully configured the Edera Falco plugin to monitor runtime activity in protected zones. By combining Edera’s hypervisor-based isolation with Falco’s eBPF-powered threat detection, you now have deep visibility into syscalls, file access, network connections, and process execution—all without compromising zone security.
Happy threat hunting.