Hi everyone. I'm pretty new to OpenClaw and trying to secure my setup. I'm running the Nano Claw on a home Ubuntu server.
I saw that Claude Code can execute subprocess commands, which is powerful but also a bit scary. I read about AppArmor being a way to lock that down. Can someone walk me through the basic steps? Like, how do I create a profile for it, and what kind of rules should I start with to allow it to work but not do anything risky? I learn best with concrete examples.
Hey, great question! AppArmor is a solid choice for this. I ran into a similar need when I was playing with Claude Code in my own lab.
Start by checking if it's already confined: `aa-status | grep -i claw`. If not, you can generate a base profile with `aa-genprof` while running some typical tasks. But for a tighter fit, I'd write a minimal one manually. Here's a skeleton to put in `/etc/apparmor.d/claude-code`:
```
profile claude-code /usr/local/bin/claude-code {
# Basic runtime access
/usr/local/bin/claude-code mr,
/usr/lib/**.so* mr,
# Allow writing to its own cache/tmp, deny elsewhere
/tmp/claude-* rw,
deny /etc/** w,
deny /home/*/** wlx,
# Maybe allow read for your project dirs only
/home/user503/projects/** r,
}
```
Reload with `sudo apparmor_parser -r /etc/apparmor.d/claude-code`. The key is to start super restrictive, then watch `/var/log/audit/audit.log` or `journalctl` for denials when you run actual tasks, and loosen only what's needed.
Honestly, after my own near-miss, I'd also pair this with a dedicated network namespace and cgroups limits. AppArmor stops file system mischief, but won't limit fork bombs or network calls.
Better safe than pwned.
That's a really helpful skeleton, thanks! I'm definitely trying this on my test VM first.
I'm a bit nervous about manually editing the profile though. You mentioned starting restrictive and watching for denials. If I lock it down too much and Claude Code can't start at all, how do I even see the logs to fix it? Do I need to have a separate terminal open with `journalctl -f` running before I launch it, or is there a better way?
Good skeleton, but the `/usr/lib/**.so*` rule is a bit too permissive for a hardening exercise. It grants memory read access to all shared objects under `/usr/lib`, which includes a vast number of unrelated libraries. A more precise baseline would be to allow `/**/lib*.so*` for standard linker resolution, then specifically deny sensitive paths like `/usr/lib/debug/**`.
Also, the mention of network namespaces is critical. An AppArmor profile without network rules defaults to allowing all network access. You need explicit `deny network` or specific `network` rules to restrict that vector.