Parse AppArmor denial logs, generate policy rules, and close profile gaps — automatically
What it is
AppArmor denials pile up in journals and audit logs. Reading them manually, understanding what each entry means, deciding which paths to generalise and which to block — that work takes hours and is easy to get wrong.
The faaleoleo AppArmor Log Parser automates the entire workflow. It reads journalctl, auditd, and syslog output, parses every denial into structured data, generalises specific paths into correct AppArmor wildcards, and flags security-sensitive rules that should stay blocked. Then it compares the suggested rules against your deployed profiles and tells you exactly what is missing.
Five commands cover the full lifecycle: from a quick denial count to a complete profile gap analysis. Output in text, JSON, or CSV — readable on the terminal or piped directly into your CI pipeline or SIEM.
# Parse denials from the system journal journalctl | grep DENIED | aa-log-parser parse 47 denials · 12 operations · 23 unique paths # Generate AppArmor rules automatically aa-log-parser generate -i denials.log \ --profile-name nginx /var/lib/nginx/** rw, [HIGH] /run/nginx/*.pid rwk, [MEDIUM] /etc/nginx/** r, [HIGH] # Full gap analysis vs deployed profile aa-log-parser analyze -i denials.log \ --profile-name nginx 3 rules covered · 5 missing · 2 security blocks # JSON output for CI / dashboards aa-log-parser analyze -i denials.log \ --profile-name nginx --format json
Why use it
AppArmor is one of the most effective Linux security controls available. The reason most teams run it in complain mode — or not at all — is the manual work required to get profiles right.
Reading denial logs manually, mapping operations to AppArmor permissions, deciding which paths need wildcards — the parser does all of that automatically. A workflow that used to take an afternoon takes one command.
The parser flags 11 sensitive path patterns (/etc/shadow, SSH keys, kernel modules, block devices) and 6 dangerous capabilities before you add them to a profile. Intentional denials are reported separately — never silently dropped.
Compare suggested rules against your deployed /etc/apparmor.d/ profiles. Get three lists: rules already covered, rules that are missing, and rules that are intentionally blocked. No guesswork.
Auto-detects journalctl (quoted key-value pairs), auditd (unquoted), and syslog — per line. Mixed-format files work without any flags. Pipe directly from journalctl or pass a log file.
The --format json flag produces structured output with timestamps, denial lists, rule suggestions, and comparison metadata. Pipe it to your pipeline, SIEM, or compliance dashboard without post-processing.
Ships as a self-contained binary built with PyInstaller. Drop it on any Linux server — no Python runtime, no package manager, no venv. Zero runtime dependencies either way.
Use cases
From profile creation to compliance evidence — every AppArmor workflow is covered.
Run a service in complain mode, capture denials, run generate. Get a working rule set in minutes rather than iterating through logs by hand over days.
Identify the exact paths your production services access and build tight, accurate profiles — without resorting to overly permissive wildcards or disabling enforcement.
Run aa-log-parser analyze --format json in your pipeline. Fail the build if new denials appear that are not covered by the deployed profile. Keep policy drift out of production.
Export structured JSON or CSV reports of denial events, applied rules, and security blocks. Feed them directly into audit evidence packages for NIS2, ISO 27001, or SOC 2 assessments.
Use summary for a fast health check of denial volume and operations. Use analyze after an incident to understand exactly what AppArmor blocked and why.
Run compare across all services in your fleet. Surface profiles with significant gaps between what is being denied and what is covered — across tens or hundreds of hosts.
Features
A focused tool with a well-defined scope: parse denials, generate rules, close gaps. 429+ tests and zero external dependencies.
Journalctl (quoted), auditd (unquoted), and syslog formats detected per line — mixed files work without flags.
Specific paths become correct AppArmor wildcards: /var/lib/nginx/cache/x.bin → /var/lib/nginx/**. Controlled by configurable prefix lists.
11 sensitive path patterns and 6 dangerous POSIX capabilities flagged as security blocks — reported separately, never silently merged into suggested rules.
Every rule gets a priority: high (config/data), medium (log/runtime), low (everything else), critical (security blocks). Focus on what matters first.
Compares suggested rules against deployed /etc/apparmor.d/ profiles. Three-way split: covered, missing, security blocks.
parse · generate · analyze · compare · summary — from a quick denial count to a full profile audit.
Human-readable text for the terminal, JSON for pipelines and dashboards, CSV for spreadsheets and audit submissions.
Pass --profile-name nginx — the parser resolves it to usr.sbin.nginx automatically. Override with an explicit path for development profiles.
PyInstaller build produces a single executable for Linux x86_64. No Python runtime, no package manager, no installation — copy and run.
pytest suite covering models, parser, formatters, CLI, constants, edge cases, security analysis, and integration — plus property-based tests with Hypothesis.
Pure Python standard library. Nothing to install beyond Python 3.7+ itself — or use the binary and skip Python entirely.
Sensitive paths, dangerous capabilities, and generalizable prefixes centralised in constants.py — tune them to your environment without touching parser logic.
Quick start
Requires Python 3.7+ or use the pre-built binary. Linux only — AppArmor is a Linux kernel module.
Install from the repository via pip, or download the self-contained binary — no Python runtime required on the target system.
git clone \
https://git.faaleoleo.io/\
faaleoleo-dev-team/aa-log-parser
cd aa-log-parser
# Option A — pip
pip install -e .
# Option B — self-contained binary
./build.sh
sudo cp dist/aa-log-parser /usr/local/bin/
Export AppArmor denials from the system journal or an audit log file. The parser auto-detects the format per line.
journalctl -k | grep -i apparmor \
| grep DENIED > denials.log
# Or pipe directly:
journalctl -k | grep DENIED \
| aa-log-parser parse
Generate rules for your service profile, or run a full gap analysis against the currently deployed profile.
aa-log-parser generate \
-i denials.log \
--profile-name nginx
aa-log-parser analyze \
-i denials.log \
--profile-name nginx \
--format json -o report.json
Released under the BSD 2-Clause license. Use it freely in commercial products, internal tooling, security pipelines, and compliance workflows.
↓ Download from Forgejo