- Posted on
- • Artificial Intelligence
Artificial Intelligence AppArmor Management
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence AppArmor Management: Lock Down Your AI Workloads with Bash
Your AI service can load gigabytes of models, open network sockets, and touch GPUs and shared memory. That’s a lot of attack surface. One command injection or library RCE, and your API keys, models, or training data may be gone. AppArmor gives you a simple, auditable way to sandbox AI processes on Linux—without rewriting your app.
This guide shows you how to confine AI workloads with AppArmor using Bash-friendly commands: install, design, enforce, iterate, and ship.
Why AppArmor for AI?
AI stacks are dependency-heavy. Python + CUDA + BLAS + drivers + HTTP libraries = a big blast radius if something goes wrong.
Models and datasets are valuable IP. A narrow read-only policy around model directories reduces exfil risk.
GPU access is special. Device nodes like /dev/nvidia0 or /dev/dri/renderD128 are sensitive—lock them down to only what’s needed.
Network isn’t “all or nothing.” AppArmor can restrict network families/types (pair with firewall for ports/hosts).
Easier profiles. Compared to SELinux, AppArmor profiles are often faster to author and iterate for app-centric sandboxes.
AppArmor complements containers and seccomp. You can use it directly on the host, in containers (Docker, Kubernetes), or with systemd services.
Install and enable AppArmor
Check if AppArmor is enabled:
aa-status || true
cat /sys/module/apparmor/parameters/enabled 2>/dev/null
If you see “enabled” or profiles listed, you’re good. Otherwise, install the tools:
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra
sudo systemctl enable --now apparmor
- Fedora/RHEL/CentOS (dnf):
sudo dnf install apparmor apparmor-utils apparmor-parser
Note: Fedora/RHEL default to SELinux. AppArmor may require kernel boot parameters and is not enabled by default. Prefer SELinux on these systems if you don’t have a specific reason to use AppArmor. If you choose AppArmor, consult your distro docs for enabling it at boot (e.g., kernel params like apparmor=1).
- openSUSE/SLE (zypper):
sudo zypper refresh
sudo zypper install apparmor apparmor-utils
sudo systemctl enable --now apparmor
Verify again:
sudo aa-status
Core workflow: 5 practical steps
1) Inventory what your AI app actually uses
Before writing a profile, watch a running instance and note:
Files and directories (models, logs, caches, configs)
Devices (GPUs: /dev/nvidia*, /dev/dri/renderD*)
Sockets (inet/inet6 stream or dgram)
Temporary paths (/tmp, /dev/shm)
Subprocesses (e.g., torchrun, uvicorn)
Useful commands:
# Start your app normally, then:
PID=$(pgrep -f 'python3 .*serve')
sudo lsof -p "$PID" | awk '{print $4,$9}' | sort -u
ss -ptn | grep "$PID"
ls -l /dev/nvidia* /dev/dri/renderD* 2>/dev/null || true
2) Draft a minimal AppArmor profile for your AI service
Create a named profile you can attach with aa-exec. This example confines a Python inference server that:
Reads models from /opt/ai/models (read-only, mmap allowed)
Writes logs to /var/log/ai
Uses GPUs
Talks TCP over IPv4/IPv6 (limit ports/hosts with a firewall)
Create the profile:
sudoedit /etc/apparmor.d/ai-infer
Paste:
#include <tunables/global>
profile ai-infer flags=(attach_disconnected,mediate_deleted) {
# Low-level sanity and DNS
#include <abstractions/base>
#include <abstractions/nameservice>
# Network (AppArmor can restrict family/type, not ports)
network inet stream,
network inet6 stream,
# Python entrypoint and code
/usr/bin/python3 ix,
/srv/ai/serve.py r,
# Site packages and shared libs (read-only)
/usr/lib/** r,
/lib/** r,
/usr/local/lib/** r,
# Models: read + mmap (+ lock if needed)
/opt/ai/models/** rmk,
# Logs and caches
/var/log/ai/** rwk,
owner /tmp/** rw,
owner @{HOME}/.cache/ai/** rwmk,
# GPU access (NVIDIA + generic render nodes)
/dev/nvidiactl rw,
/dev/nvidia-uvm rw,
/dev/nvidia[0-9]* rw,
/dev/dri/renderD* rw,
# Proc is mostly read-only; protect sysctl
/proc/** r,
deny /proc/sys/** w,
# Keep system files safe
deny /etc/** w,
deny @{HOME}/** w,
}
Notes:
Adjust paths (Python, code, models, logs) to your environment.
If you bind to a port <1024, you may also need:
capability net_bind_service,For AMD/Intel GPUs, render nodes are usually at /dev/dri/renderD* (keep those rules if needed).
For Torch/TensorFlow that memory-map big files, ensure “m” is present on model paths.
3) Load the profile and run your app under it
# Load/replace the profile
sudo apparmor_parser -r -W /etc/apparmor.d/ai-infer
# Start in complain mode to learn without blocking
sudo aa-complain ai-infer
# Run your app under the profile
aa-exec -p ai-infer -- /usr/bin/python3 /srv/ai/serve.py --port 8080
Alternatively, you can reload all profiles:
sudo systemctl reload apparmor 2>/dev/null || true
4) Iterate using logs, then enforce
Exercise your API (load a model, run inference, log, use GPU), watch for denials, and refine:
# Watch kernel audit for AppArmor denials
sudo journalctl -k -g 'apparmor' -f
# or
dmesg | grep -i apparmor
Semi-automate rule suggestions:
sudo aa-logprof
When satisfied:
sudo aa-enforce ai-infer
Re-run your app under the enforced profile. If something breaks, temporarily flip back:
sudo aa-complain ai-infer
5) Ship it: systemd, Docker, Kubernetes
- systemd (wrap ExecStart with aa-exec):
sudo tee /etc/systemd/system/ai-infer.service >/dev/null <<'UNIT'
[Unit]
Description=AI Inference Service (AppArmor confined)
After=network.target
[Service]
User=ai
Group=ai
WorkingDirectory=/srv/ai
ExecStart=/usr/bin/aa-exec -p ai-infer -- /usr/bin/python3 /srv/ai/serve.py --port 8080
Restart=on-failure
[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable --now ai-infer
- Docker:
# Ensure ai-infer profile is loaded on the host first
docker run --rm -p 8080:8080 --security-opt apparmor=ai-infer my-ai-image:latest
- Kubernetes (node must have the profile loaded as localhost/ai-infer):
apiVersion: v1
kind: Pod
metadata:
name: ai-infer
annotations:
container.apparmor.security.beta.kubernetes.io/ai: localhost/ai-infer
spec:
containers:
- name: ai
image: my-ai-image:latest
args: ["aa-exec","-p","ai-infer","--","/usr/bin/python3","/srv/ai/serve.py","--port","8080"]
securityContext:
allowPrivilegeEscalation: false
Tip: Some runtimes can apply a profile without wrapping aa-exec if you specify the profile name; wrapping works everywhere.
Practical patterns for AI sandboxes
GPU devices:
- NVIDIA: /dev/nvidiactl, /dev/nvidia-uvm, /dev/nvidia[0-9]*
- AMD/Intel: /dev/dri/renderD*
- Keep access rw to just what you need; don’t allow /dev/mem or /dev/kmem.
Models, checkpoints, and tokenizers:
- Read-only plus mmap: use r and m.
- Separate writable fine-tune outputs to a dedicated directory and allow rwk only there.
Temporary and shared memory:
- owner /tmp/** rw, and consider restricting to a subdir your app creates.
- If you use /dev/shm heavily, add explicit allowances.
Networking:
- AppArmor can limit protocol family/type (e.g., inet stream). For specific ports/hosts, combine with nftables/firewalld.
Python ecosystems:
- Prefer explicit file and library paths over broad wildcards.
- If your framework spawns helpers (e.g., torchrun), allow those binaries with ix rules.
Real-world example: lock down a text-generation API
Scenario: A Python FastAPI server loads LLM weights from /opt/ai/models, serves on 8080, logs to /var/log/ai, uses an NVIDIA GPU, and caches to ~/.cache/ai.
Use the profile above (ai-infer), adjust paths.
Start in complain mode, hit endpoints, watch logs, run aa-logprof.
Enforce and deploy via systemd or Docker with the same profile.
Pair with a firewall rule to restrict egress to required services only.
Troubleshooting quick hits
Are profiles loaded?
sudo aa-statusSee what profile a process is under:
cat /proc/$PID/attr/currentTemporarily disable a profile:
sudo aa-disable ai-inferSyntax check a profile:
sudo apparmor_parser -Q /etc/apparmor.d/ai-inferNo denials showing? Make sure you’re looking at kernel logs:
sudo journalctl -k -g apparmor -f
Conclusion and next steps
Your AI workloads don’t need blanket access to the machine. With a few focused rules, AppArmor can narrow your risk without slowing down development.
Action item 1: Install AppArmor tools (apt/dnf/zypper) and verify with aa-status.
Action item 2: Constrain one AI service this week using the ai-infer profile.
Action item 3: Iterate with complain mode, aa-logprof, and then enforce.
Action item 4: Ship via systemd, Docker, or Kubernetes annotations.
Want deeper coverage (seccomp filters, network policies, read-only roots, eBPF)? Tell me what you run (framework, GPU, deployment target), and I’ll help you tailor a production-grade sandbox.