AppArmor
AppArmor provides Mandatory Access Control (MAC) for agent processes. Each agent gets a unique AppArmor profile derived from its manifest. The kernel enforces the profile independently of agentd.
Profile Generation
At spawn time, profile_gen.rs generates an AppArmor profile for the agent:
profile scarab-agent-<uuid> {
# Base abstractions
#include <abstractions/base>
# Workspace access (derived from fs.read/fs.write capabilities)
/home/agent/workspace/** rw,
/home/agent/workspace r,
# No network (if policy: none)
deny network,
# Deny everything else
deny /** rwxmlink,
}
The profile name includes the agent UUID, ensuring each agent gets isolated enforcement.
File Access Rules
File rules are derived from the agent's fs.read and fs.write capabilities:
| Capability | AppArmor rule |
|---|---|
fs.read | /** r, (any file, read-only) |
fs.read:/home/agent/** | /home/agent/** r, |
fs.write:/home/agent/workspace/** | /home/agent/workspace/** rw, |
Network Rules
Network rules are derived from spec.network.policy:
| Policy | AppArmor Rule |
|---|---|
none | deny network, |
local | network inet stream, network inet dgram, (no external) |
allowlist | network inet stream, with per-IP rules |
full | network, |
Profile Loading
Generated profiles are loaded into the kernel's AppArmor subsystem before the agent binary is exec'd. The agentd process must have permission to load AppArmor profiles (typically requires root or CAP_MAC_ADMIN).
Validation
# Run AppArmor enforcement tests (requires root + AppArmor enabled)
sudo cargo test apparmor
Tests verify that file access outside declared scopes is denied by AppArmor.
Debugging
If an agent's operations are unexpectedly denied, check the kernel audit log:
dmesg | grep apparmor | grep DENIED
Or:
journalctl -k | grep apparmor
AppArmor denials also feed back into the anomaly detector as kernel_denial events.