A production-quality LD_PRELOAD interceptor library that provides universal agent protection by intercepting exec-family syscalls and consulting the Rampart policy server before execution.
The compiled library is not distributed in the repository. Build it from source:
cd preload
make # builds librampart.so (Linux) or librampart.dylib (macOS)
make install # copies to ~/.rampart/lib/Dependencies: gcc, libcurl-dev, libpthread
# Ubuntu/Debian
sudo apt install build-essential libcurl4-openssl-dev
# macOS
brew install curlrampart setup runs make install automatically when it detects the preload integration mode.
The Rampart preload library (librampart.so / librampart.dylib) works by:
- Intercepting exec-family system calls (
execve,execvp,system,popen, etc.) - Consulting the Rampart policy server via HTTP before allowing execution
- Failing open (allowing execution) if the policy server is unreachable
- Providing comprehensive logging and debugging capabilities
Agent Process → calls execve() → librampart.so intercepts
→ HTTP POST to rampart serve /v1/preflight/exec
→ allowed:true → call real execve via dlsym(RTLD_NEXT)
→ allowed:false → errno=EPERM, return -1
→ HTTP fails → fail-open (exec through)
- GCC or Clang compiler
- libcurl development headers
- pthread support
- Make
Linux (Ubuntu/Debian):
sudo apt-get install build-essential libcurl4-openssl-devLinux (CentOS/RHEL):
sudo yum install gcc libcurl-develmacOS:
# Install Xcode command line tools
xcode-select --install
# libcurl is included with macOS# Standard build
make
# Debug build with symbols
make debug
# AddressSanitizer build for development
make asan
# Cross-platform - automatically detects Linux/macOS
make allBuild outputs:
- Linux:
librampart.so - macOS:
librampart.dylib
Linux:
export LD_PRELOAD="./librampart.so"
export RAMPART_URL="http://127.0.0.1:19090"
export RAMPART_TOKEN="your-token-here"
# Run any command with protection
python my_agent.py
node agent.js
./my_binarymacOS:
export DYLD_INSERT_LIBRARIES="./librampart.dylib"
export RAMPART_URL="http://127.0.0.1:19090"
export RAMPART_TOKEN="your-token-here"
# Run any command with protection
python my_agent.py# The rampart CLI will handle all environment setup
rampart preload -- python my_agent.py
rampart preload -- codex
rampart preload --mode monitor -- risky_tool| Variable | Default | Description |
|---|---|---|
RAMPART_URL |
http://127.0.0.1:19090 |
Policy server URL |
RAMPART_TOKEN |
(none) | Bearer auth token |
RAMPART_MODE |
enforce |
enforce / monitor / disabled |
RAMPART_FAIL_OPEN |
1 |
Fail-open when server unreachable (1=yes, 0=no) |
RAMPART_AGENT |
preload |
Agent name for audit logs |
RAMPART_SESSION |
preload-<pid> |
Session ID for tracking |
RAMPART_DEBUG |
0 |
Debug logging to stderr (1=on, 0=off) |
- enforce: Block denied commands, allow approved commands
- monitor: Log all commands but never block (audit mode)
- disabled: Pass through all commands without policy checks
The library intercepts these libc functions:
execve(path, argv, envp)— Primary exec syscallexecvp(file, argv)— PATH-resolved execexecvpe(file, argv, envp)— PATH-resolved with environment (Linux only)system(command)— Shell command executionpopen(command, type)— Pipe to shell commandposix_spawn(...)— Modern spawn API (heavily used on macOS)
Run the comprehensive test suite:
# Run all tests
./test_preload.sh
# Build and test
make testTest coverage:
- Library loading without crashes
- Debug output functionality
- Policy enforcement (when
rampart serveis running) - Fail-open behavior (when server is unreachable)
system()andpopen()interception- Monitor and disabled modes
- Child process inheritance
Basic functionality:
# Test library loads
LD_PRELOAD=./librampart.so echo "hello"
# Test debug output
RAMPART_DEBUG=1 LD_PRELOAD=./librampart.so echo "hello" 2>&1 | grep rampart
# Test fail-open (server unreachable)
RAMPART_URL=http://127.0.0.1:99999 LD_PRELOAD=./librampart.so echo "should work"Policy enforcement (requires rampart serve running):
export LD_PRELOAD="./librampart.so"
export RAMPART_URL="http://127.0.0.1:19090"
export RAMPART_TOKEN="your-token"
# Should work (typically allowed)
echo "hello from preload"
ls /tmp
# Should be denied by policy (if configured)
rm -rf /tmp/test
curl http://example.com# Install to user directory
make install
# Library will be installed to ~/.rampart/lib/The rampart CLI will automatically find libraries in:
~/.rampart/lib/librampart.{so,dylib}/usr/local/lib/librampart.{so,dylib}- Next to the
rampartbinary
The library is optimized for minimal latency:
- Persistent HTTP keep-alive connection — One connection per process, reused for all policy checks
- Manual JSON parsing — No external JSON library dependencies
- Fail-fast on errors — Immediate fail-open if server unreachable
- Thread-safe — Uses pthread mutex for curl handle protection
Target performance:
- < 1ms per policy check (Unix domain socket)
- < 3ms per policy check (TCP to localhost)
- < 0.01ms fail-open path (server unreachable)
- Coverage: ~95% of dynamically-linked binaries
- Mechanism:
LD_PRELOAD - Works with: Most user-installed software, Python, Node.js, Go binaries
- Limitations: Static binaries cannot be intercepted
- Coverage: ~70-85% in typical developer environments
- Mechanism:
DYLD_INSERT_LIBRARIES - Works with: Homebrew packages, nvm/Node.js, pyenv/Python, Go binaries
- System Integrity Protection (SIP) blocks system binaries but allows user software
- Limitations:
/usr/bin/*and/System/*binaries are protected- Apple-signed hardened binaries may be protected
- Static binaries cannot be intercepted
- Not supported. Use native hooks or direct Rampart API integration.
This library is designed to protect against hallucinating/manipulated AI agents, not adversarial human attackers.
What it catches:
- AI agent executing
rm -rf / - Malicious skills/plugins running credential theft commands
- Unintended network exfiltration via
curl/wget - Any exec call from the protected process tree
What it does NOT catch:
- Agent explicitly unsetting
LD_PRELOADbefore exec (deliberate bypass) - Direct syscalls bypassing libc (requires assembly knowledge)
- Statically-linked binaries (no dynamic linker)
- Non-exec file operations (
open(),connect())
- Low against determined human attackers
- High against AI agents (they don't know to bypass preload)
- Perfect against accidental/hallucinated dangerous commands
- Static binaries: Cannot be intercepted (no dynamic linking)
- macOS SIP: System binaries are protected and cannot be intercepted
- Direct syscalls: Rare, but possible to bypass libc wrappers
- Manual bypass: Sophisticated attackers can unset
LD_PRELOAD - Non-exec attacks: File system operations outside of exec are not monitored
- Zero undefined behavior — Clean compilation with
-Wall -Wextra -Werror -pedantic - Thread-safe — All global state protected by mutexes
- Memory leak free — Every
malloc()has matchingfree() - Minimal dependencies — Only libcurl and pthreads
Enable debug logging:
export RAMPART_DEBUG=1
LD_PRELOAD=./librampart.so your_command 2>&1 | grep rampartUse AddressSanitizer for development:
make asan
RAMPART_DEBUG=1 LD_PRELOAD=./librampart.so your_command- Maintain < 600 lines in
librampart.c - All changes must pass
make test - Test on both Linux and macOS
- Run AddressSanitizer builds before submitting
- Update tests for new functionality
Library won't load:
- Check that libcurl is installed
- Verify library architecture matches binary (64-bit vs 32-bit)
- Try
ldd librampart.so(Linux) orotool -L librampart.dylib(macOS)
Commands not being intercepted:
- Enable debug logging with
RAMPART_DEBUG=1 - Check that binary is dynamically linked:
file your_binary - On macOS, check if binary is SIP-protected:
codesign -dv your_binary
Server connection fails:
- Verify
rampart serveis running on the configured port - Check
RAMPART_URLandRAMPART_TOKENare correct - Test server directly:
curl -H "Authorization: Bearer $RAMPART_TOKEN" $RAMPART_URL/health
Performance issues:
- Check if keep-alive connections are working (server logs)
- Monitor network latency to policy server
- Consider using Unix domain socket (future enhancement)
See the main Rampart repository for license information.