eBPF-based enforcement that blocks unexpected file access, network calls, and subprocess spawning — before they complete. Zero code changes in the agent.
LSM hooks run synchronously inside the kernel before the syscall returns — the process never sees a file descriptor, socket, or child PID for a denied resource.
BPF LSM hooks block at the kernel boundary. Denied syscalls return -EPERM before any user-space code runs.
Tracks agent process trees by PID via fork/exec/exit tracepoints. No false positives from unrelated processes sharing the same comm name.
SSE-based web dashboard embedded in the binary. Every ALLOW and BLOCK event streams live with timestamps and process context.
Compiled once, runs across kernels. BTF-based relocation means one pre-built binary works on Ubuntu 22.04 through the latest kernel.
curl -fsSL https://github.com/VectorInstitute/vigil/releases/latest/download/install.sh | sudo bash
Installs the vigil binary and built-in profiles to /usr/local/bin and /usr/lib/vigil/profiles.
# Requires: clang, llvm, bpftool, linux-headers, Go 1.22+
git clone https://github.com/VectorInstitute/vigil
cd vigil
make # builds BPF + Go binary
Add lsm=bpf to your kernel boot parameters:
# /etc/default/grub
GRUB_CMDLINE_LINUX="lsm=bpf"
sudo update-grub && sudo reboot
# Watch an AI agent with the built-in profile
sudo vigil watch --framework gemini-cli
# With real-time web UI at http://localhost:7394
sudo vigil watch --framework claude-code --ui --port 7394
# Custom profile
sudo vigil watch --profile /path/to/profile.yaml
# List built-in profiles
vigil profile list
AI agents spawn many child processes — node, sh, python3, git — that share comm names with unrelated system processes. Without lineage tracking, vigil would either miss agent children or flood the event stream with noise from VS Code, SSH daemons, and cron jobs.
Name the agent's root process. For Gemini CLI: entry_comm: gemini. For Claude Code: entry_comm: claude.
When a process exec's to entry_comm, its PID is added to the watched_pids BPF hash map.
When a watched PID forks, the child PID inherits membership in watched_pids automatically.
All syscall tracepoints check watched_pids before emitting an event. Only agent process tree events reach the ring buffer.
PIDs are removed from watched_pids on exit, preventing false positives from PID reuse.
# profiles/gemini-cli.yaml
entry_comm: gemini # root process to track
# gemini forks → node; vigil tracks node as part of gemini's tree.
# VS Code's node is a different PID lineage — completely invisible.
Profiles define the expected behavioral envelope for an AI workload. Each profile specifies denied paths, allowed networks, allowed subprocesses, and the entry process to track.
| Profile | Entry process | Default policy | Status |
|---|---|---|---|
ollama |
ollama |
deny | Available |
claude-code |
claude |
allow | Available |
gemini-cli |
gemini |
allow | Available |
vllm |
— | — | Coming soon |
llamacpp |
— | — | Coming soon |
name: my-agent
version: "1.0"
default_policy: allow
entry_comm: my-agent # root process comm (max 15 chars)
denied_paths:
- /etc/shadow
- /root/.ssh/**
- /**/.aws/credentials
allowed_networks:
- 127.0.0.0/8
- ::1/128
- 0.0.0.0/0 # or restrict to specific CIDRs
allowed_commands:
- my-agent
- node
- git