AppArmor Log Parser
Parse AppArmor denial logs, generate policy rules, and close profile gaps — automatically
What it is
From raw denial log to AppArmor rule — in one command
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
Stop analysing logs by hand
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.
Rules in seconds, not hours
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.
Security blocks before policy mistakes
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.
Exact profile gap analysis
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.
Any log format, mixed files
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.
CI-ready JSON output
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.
No Python required on target
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
Built for the whole security team
From profile creation to compliance evidence — every AppArmor workflow is covered.
AppArmor profile development
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.
Production profile hardening
Identify the exact paths your production services access and build tight, accurate profiles — without resorting to overly permissive wildcards or disabling enforcement.
CI pipeline integration
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.
Evidence generation
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.
Incident triage
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.
Multi-profile auditing
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
Everything you need, nothing you don’t
A focused tool with a well-defined scope: parse denials, generate rules, close gaps. 429+ tests and zero external dependencies.
Auto log format detection
Journalctl (quoted), auditd (unquoted), and syslog formats detected per line — mixed files work without flags.
Smart path generalization
Specific paths become correct AppArmor wildcards: /var/lib/nginx/cache/x.bin → /var/lib/nginx/**. Controlled by configurable prefix lists.
Security block detection
11 sensitive path patterns and 6 dangerous POSIX capabilities flagged as security blocks — reported separately, never silently merged into suggested rules.
Priority labeling
Every rule gets a priority: high (config/data), medium (log/runtime), low (everything else), critical (security blocks). Focus on what matters first.
Profile gap analysis
Compares suggested rules against deployed /etc/apparmor.d/ profiles. Three-way split: covered, missing, security blocks.
5 CLI commands
parse · generate · analyze · compare · summary — from a quick denial count to a full profile audit.
Three output formats
Human-readable text for the terminal, JSON for pipelines and dashboards, CSV for spreadsheets and audit submissions.
Substring profile matching
Pass --profile-name nginx — the parser resolves it to usr.sbin.nginx automatically. Override with an explicit path for development profiles.
Self-contained binary
PyInstaller build produces a single executable for Linux x86_64. No Python runtime, no package manager, no installation — copy and run.
429+ automated tests
pytest suite covering models, parser, formatters, CLI, constants, edge cases, security analysis, and integration — plus property-based tests with Hypothesis.
Zero runtime dependencies
Pure Python standard library. Nothing to install beyond Python 3.7+ itself — or use the binary and skip Python entirely.
Configurable security lists
Sensitive paths, dangerous capabilities, and generalizable prefixes centralised in constants.py — tune them to your environment without touching parser logic.
Quick start
Up in three steps
Requires Python 3.7+ or use the pre-built binary. Linux only — AppArmor is a Linux kernel module.
Install
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-public/\
Faaleoleo-AppArmor-Parser
cd Faaleoleo-AppArmor-Parser
# Option A — pip
pip install -e .
# Option B — self-contained binary
./build.sh
sudo cp dist/aa-log-parser /usr/local/bin/
Capture denials
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 & analyze
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
Free. Open source. No strings attached.
Released under the BSD 2-Clause license. Use it freely in commercial products, internal tooling, security pipelines, and compliance workflows.
↓ Download from Forgejo