Inspiration
Autonomous coding agents are useful precisely because they can act. They read repositories, run tools, install dependencies, change files, and make decisions over several steps. That changes the security problem. It is no longer enough to ask whether one shell command is allowed. We need to ask whether the sequence of file access, process creation, repository mutation, and network activity still belongs to the task we gave the agent.
We built Aegis after studying agent-boundary failures, prompt-driven tool misuse, and dependency-install scenarios such as PATH poisoning. The common pattern is that each individual operation can look legitimate. The risk appears when normal tools are composed in the wrong order or outside their expected workspace. Aegis is our attempt to make that boundary observable and enforceable at the kernel level, while still leaving an agent able to do normal development work.
What it does
Aegis is a behavioral governance layer for a coding agent running in a Linux
container. It adds a cgroup-scoped eBPF data plane to a constrained Docker
runtime. The container runs with a read-only root filesystem, dropped Linux
capabilities, a restrictive seccomp profile, and an explicit writable
/workspace mount. The eBPF layer watches file opens, IPv4 connection
attempts, and executable activity. It can immediately reject writes outside
the workspace and can enforce paths promoted into a kernel deny map.
The Go control plane receives those fixed-size events through BPF ring buffers, keeps an ordered per-process history, and applies deterministic and contextual checks. It treats workspace escapes, repository configuration changes, high-risk command patterns, and optional outbound connections as events worth adjudicating. The event record includes the resource, recent context, trigger rule, and for gated commands, the executable SHA-256.
The key control is the execution gate. A small seccomp user-notification
supervisor can hold execve while the daemon checks episodic memory or asks a
configured model for an Allow, Deny, or AskUser response. Only an explicit
Allow arms the BPF approval needed for the command to continue. This gives us a
pre-execution decision point instead of relying only on alerts after the fact.
For repeated decisions, Aegis stores prior cases in SQLite. Executable recall is exact: the full command resource, trigger rule, and binary hash must match. For non-exec behavior, the memory layer derives a compact heuristic feature vector and uses local cosine similarity. The result is an adaptive memory layer that can avoid repeated provider calls while preserving a stricter standard for commands than for general telemetry.
How we built it
The project is split deliberately across the kernel and userspace. In C, we
wrote BPF LSM programs for file_open and socket_connect, plus a
bprm_check_security guard for execution approval. Executable and bounded argv
telemetry are captured at the sys_enter_execve tracepoint, where user argv is
available. The programs share a cgroup target map, ring buffers, and compact
map-based enforcement state. That keeps the fast path local to the kernel.
In Go, aegisd loads the BPF objects, resolves the agent container’s cgroup,
follows container recreation, reads ring buffers, scores event sequences,
manages the provider registry, retrieves prior cases, writes audit records, and
synchronizes live path blocks. We added a Unix control socket for privileged
policy revocation so a human can lift a live block without restarting the
daemon.
We designed the model integration as an OpenAI-compatible interface rather
than binding the system to a single provider. The provider registry supports
hosted and local endpoints, separate cheap and flagship models, masked key
display, and configuration through providers.json plus environment variables.
The cascade routes cases based on risk and context length; exact memory recall
is checked before a paid model call.
Codex was part of the build process, not a decorative integration. We used it while working through BPF C structures, Go ABI alignment, concurrent readers, Unix-socket control flow, provider configuration, tests, and the trajectory evaluation harness. GPT-5.6 was used to refine the adjudication prompt and the strict structured decision contract. Those experiments informed a runtime that can use GPT-5.6 or another compatible endpoint without changing the control plane.
The repository also contains the next layers of the design: Cedar policy translation and validation, a Process Reward Model training pipeline, a LinUCB bandit experiment, and trajectory-based evaluation. They exist because we wanted the architecture to address policy lifecycle, cost, and reward hacking, not merely classify one command at a time. We keep those learning components offline while their data and validation mature.
Challenges we ran into
The hardest systems question was timing. A ring-buffer event is excellent for telemetry, but a model answer received after an event cannot stop that same operation. We had to separate two paths: asynchronous observation and subsequent policy promotion for files, and a synchronous seccomp gate for the commands that need an answer before execution. The BPF execution guard then acts as a second check for scoped processes.
eBPF also forced us to be precise. BPF verifier constraints, local kernel type information, fixed-size ABI structs, map lifetime, cgroup identity, and Docker runtime details all mattered. We added a disabled-cgroup sentinel so a daemon started before its target container does not observe the host, and a fallback header path for Linux environments where local BTF extraction is unavailable.
The evaluation problem was equally important. A perfect score on a small static set can be misleading when an agent changes strategy across a workflow. That is why we added adversarial cases, a stateful trajectory environment, a held-out-set discipline in CI, and a written reward-hacking audit for the bandit work.
Accomplishments that we're proud of
- We built a real kernel-to-userspace enforcement path: cgroup-scoped BPF programs, ring-buffer ingestion, Go control plane, JSONL audit, and BPF path-map enforcement.
- We built a pre-execution command gate with seccomp user notification and a
BPF
bprm_check_securitybackstop. That is the central systems result of the project. - We preserved ordinary coding behavior inside
/workspacewhile making workspace-only writes a deterministic kernel rule. - We made memory conservative for executable decisions by binding recall to command, rule, and binary SHA-256 rather than relying on approximate command similarity.
- We built a model-agnostic provider layer, so the adjudication contract is portable across GPT-5.6, other hosted compatible models, and local services.
- We documented reward-hacking failure modes and added trajectory-oriented evaluation work instead of hiding the problem behind a single F1 score.
What we learned
We learned that agent security is mostly about interfaces between layers. Kernel hooks need a clear scope. A model needs a narrow authority. A policy needs an audit trail and a revocation path. An evaluation needs to measure security and usability together. The technically interesting part is not that a model can return “Deny.” It is building the deterministic machinery around that answer so it has a bounded, inspectable effect.
We also learned to use Codex with discipline. It accelerated exploration of unfamiliar C and concurrent Go code, but the final standard remained the same: compile it, test it, read the kernel-facing code carefully, and verify that the runtime behavior matches the claim.
What's next for Aegis
The next iteration is about hardening and evidence. We will strengthen execution-approval binding, finish the trajectory-runner integration, validate the system across supported kernels, and expand process-tree, IPv6, DNS, and policy-provenance coverage. We will continue the Cedar and learning work while giving it a role through reproducible evaluation and operational benefit. The longer-term question is whether Aegis can reduce agent risk without turning every useful action into a human approval request.

Log in or sign up for Devpost to join the conversation.