Alright, let’s cut through the marketing fluff. You’ve decided to self-host Aider because, like any sane person, you don’t want your private codebase telemetry vacuumed up by a third party. But now you’re staring at this Python script that has carte blanche to run git commands, modify your filesystem, and potentially execute arbitrary shell commands via its tool-calling abilities. The immediate, chilling question is: **what exactly is it doing right now?**
Aider, by design, is a powerful agent. It’s not a passive editor. It reasons, plans, and then *acts*—and those actions are shell-level. The default posture is terrifyingly open. Auditing its real-time behavior isn’t about reading the source; it’s about intercepting the runtime execution chain. Here’s how I’d start, from the blunt to the surgical.
First, accept that you can’t just trust the high-level logs. You need to see the actual syscalls and subprocess spawns. If you’re running it in a naive setup, you’re one hallucination away from a `rm -rf` in the wrong directory.
**Immediate, low-hang fruit: strace for the parent process**
Find Aider’s PID and trace all its children. This is noisy but definitive.
```bash
strace -f -e trace=execve -p $(pgrep -f aider) 2>&1 | grep execve
```
You’ll see every command it forks. This is your ground truth for what’s hitting the kernel.
**Next, contain it properly from the get-go**
If you’re auditing, you should already have it in a sandbox. My preference is a dedicated user namespace with reduced capabilities, bound to a cgroup. But for quick audit trails, you can run it under a wrapper that logs all commands. A simple bash trap can capture git invocations, but Aider can call more than git.
**Instrument the Python execution directly**
Since Aider uses the OpenAI API pattern for tool calls, the real action is in the handlers for those tools. The code for `execute_command` and `run_git_command` is where the rubber meets the road. But runtime auditing means intercepting *before* the subprocess runs. I’ve used a monkey-patch at launch to log every subprocess call:
```python
import subprocess
original_run = subprocess.run
def logged_run(*args, **kwargs):
import sys
print(f"[AIDER AUDIT] Command: {args[0] if args else kwargs.get('args')}", file=sys.stderr)
return original_run(*args, **kwargs)
subprocess.run = logged_run
# Then import and run aider as normal
```
Run Aider with this prepended. Now every command it attempts via `subprocess.run` hits your log.
**The real concern: transitive execution**
Aider can write and then execute scripts. Your audit trail must extend to file creation events (inotify) and subsequent exec calls. This is where a proper security layer like Ironclaw or even a gVisor boundary pays off—not just to block, but to log the attempt.
What are you all using? Have you found a cleaner way to tap into the command stream without modifying the source? I’m particularly wary of the git integration; the agent has enough context to craft malicious git commands that look benign in logs (`git config --global` comes to mind).
-- ben
Escape artist, security consultant.