Repository navigation
Feature request: emit per-access Landlock filesystem-deny events via OCSF FileActivity #1234
Description
Summary
OpenShell currently emits OCSF events for Landlock initialization (ruleset built, unavailable, enforce-failed — all ConfigStateChange / DetectionFinding class) but does not emit any events for per-access Landlock denials at runtime. This makes it impossible for downstream consumers (audit dashboards, policy-event viewers) to build an accurate filesystem-access audit trail.
Agent Diagnostic
I investigated the upstream codebase before filing this issue.
What exists today
crates/openshell-sandbox/src/sandbox/linux/landlock.rs emits:
| OCSF class | trigger |
|---|---|
ConfigStateChange (5019) severity=Informational state="applying" |
ruleset construction begins |
ConfigStateChange (5019) severity=Informational state="built" |
ruleset built |
DetectionFinding (2004) uid=landlock-unavailable |
prepare/enforce failed (best-effort) |
ConfigStateChange (5019) severity=Medium state="degraded" |
path skipped (non-NotFound, best-effort) |
What is missing
Once restrict_self() is called, the kernel enforces the ruleset transparently. Denied filesystem accesses return EACCES/EPERM to the agent process making the syscall. The sandbox supervisor (running outside the restricted context) receives no notification.
The openshell-ocsf crate has no FileActivity event class — the OcsfEvent enum in crates/openshell-ocsf/src/events/mod.rs supports class_uids: 4001, 4002, 4007, 1007, 2004, 6002, 5019, and 0. There is no OCSF File System Activity (class_uid 1001–1006) variant.
Proposed Solution
One or more of the following approaches would address this:
Option A — eBPF LSM hook (preferred)
Attach a bpf_lsm_file_open / bpf_lsm_path_* BPF-LSM hook in the supervisor (before restrict_self()) that observes denied accesses and streams them over a ring-buffer to the supervisor process. The supervisor can then emit OCSF FileActivity events to the same log-push channel.
Requirements: kernel 5.7+ with CONFIG_BPF_LSM, CAP_BPF + CAP_PERFMON granted to the supervisor.
Option B — fanotify with FAN_OPEN_PERM
Register a fanotify group in the supervisor before restrict_self(). This requires CAP_SYS_ADMIN and has higher overhead than eBPF, but is more broadly available.
Option C — OCSF FileActivity class only (minimal)
If a monitoring mechanism already exists or is added separately, add a FileActivity OCSF event class to openshell-ocsf so structured events can be emitted and forwarded via the existing LogPushLayer / WatchSandbox gRPC stream.
Desired event schema
{
"class_uid": 1001,
"event_type": "FS_DENY",
"action_id": 2,
"severity_id": 3,
"actor": { "process": { "name": "/usr/local/bin/agent", "pid": 1234 } },
"file": { "path": "/etc/shadow" },
"message": "Landlock denied open /etc/shadow",
"metadata": { "version": "1.7.0", "product": { "name": "OpenShell" } }
}Impact
Without per-access events, downstream consumers (e.g. ellarun's logs_gateway.jsonl audit trail and policy-events dashboard) must synthesise filesystem policy violations from agent observations — an unreliable approach that breaks the audit-trail guarantee. This was filed as ellarun internal ticket ELR-124.
References
- Landlock docs: https://docs.kernel.org/userspace-api/landlock.html
- OCSF File System Activity: https://schema.ocsf.io/1.7.0/classes/file_activity
- BPF LSM: https://docs.kernel.org/bpf/prog_lsm.html
Activity