AppArmor Language Server
Full-featured language support for AppArmor profiles,
powered by apparmor-language-server.
Features
| Feature |
Details |
| Completions |
Rule keywords with snippets, all Linux capabilities, network families/types/protocols, signal names, ptrace/mount/dbus/unix permissions, file permission strings, @{variable} names, include abstraction paths, live filesystem path completion |
| Hover |
Rich documentation for every keyword, capability, permission character, network family, profile flag, and variable |
| Diagnostics |
Unknown capabilities, network types, signal/ptrace/mount/dbus/unix/mqueue/rlimit values; dangerous unconfined exec modes; conflicting flags; conflicting allow+deny; undefined variables; unused variables; unused preamble includes; missing include/abi targets; missing abi declaration; missing tunables/global include; abstractions/nameservice used where nameservice-strict suffices; missing owner qualifier on @{HOME}, /home/, @{run}/user/, /run/user/, and /tmp/ file rules; bare * or [0-9]* in the PID or TID position of a /proc/ path; literal path segment matching a plain variable value in scope (suggests variable substitution); broad recursive home access (@{HOME}/**, @{HOMEDIRS}/**) without abstractions/private-files-strict; @{HOME}/** paired with a deny @{HOME}/.** rule that can be collapsed to @{HOME}/[^.]**; attach_disconnected flag used without .path= qualifier; attach_disconnected.path or attach_disconnected.ipc used bare without =VALUE (error); attach_disconnected.path= value not starting with / or not following the /att/<profile-name>/ convention; unclosed profiles; subsumed file rules and rules subsumed by broader siblings, transitively included abstractions, or all,; profile name does not match document filename; profile name defined in more than one document; missing include if exists <local/…> at end of profile; inline comment (trailing comment on a rule or directive) missing space after #; and more — plus apparmor_parser syntax errors when available |
| Code Actions |
Quick fixes for flagged diagnostics (e.g. remove duplicate capabilities, add missing abi declaration, add missing tunables/global include, remove unused variable, remove unused include, add missing owner qualifier, replace bare /proc/ PID/TID wildcards with @{pid}/@{pids}/@{tid}, replace literal path segment with matching variable reference, add missing abstractions/private-files-strict include or rewrite @{HOME}/** to @{HOME}/[^.]** (two alternative fixes for broad home access), collapse @{HOME}/** + deny @{HOME}/.** pair to @{HOME}/[^.]**, rename profile to match filename, add missing include if exists <local/…>, replace bare attach_disconnected or bare attach_disconnected.path with the qualified .path= form, correct a non-conventional attach_disconnected.path= value, add space after # in comments, "Did you mean X?" typo corrections for unknown capabilities, permission tokens, flags, keywords, and undefined variable names, annotate to suppress a warning) |
| Document Links |
include and abi paths rendered as inline hyperlinks; clicking navigates to the target file |
| Go to Definition |
Jump from include <…> to the target file; jump to profile definitions; follow exec transitions and change_profile rules to the target profile |
| Call Hierarchy |
Incoming: which profiles exec-transition or change_profile into a given profile; outgoing: which profiles a given profile transitions to |
| Formatting |
Normalise indentation, sort capability and permission lists, ensure trailing commas, align consecutive file rules, wrap long rules, normalise #include → include, collapse blank lines |
| Semantic Tokens |
Theme-aware syntax highlighting for rule keywords, qualifiers, paths, permissions, variables, and more |
| Document Symbols |
Outline view showing all profiles, hats, capabilities, file rules, includes and variables |
| Folding |
Collapse profile, hat, if, and qualifier blocks |
| References |
Find all uses of a variable across open documents |
| Rename |
Rename a variable (@{VAR}) across all open documents |
| Selection Range |
Expand selection from rule → block → profile on each keypress |
Requirements
The extension is a client for
apparmor-language-server.
Install the server before using this extension.
Install from snap (recommended)
sudo snap install apparmor-language-server
Install from PyPI
pip install apparmor-language-server
Install from source
git clone https://gitlab.com/apparmor/apparmor-language-server
cd apparmor-language-server
pip install .
Extension Settings
| Setting |
Default |
Description |
apparmor.serverPath |
"" |
Explicit path to the apparmor-language-server executable. Takes precedence over all other settings. |
apparmor.pythonPath |
"" |
Path to a Python interpreter that has apparmor-language-server installed. Consulted when the server is not found on PATH. |
apparmor.diagnostics.enable |
true |
Enable or disable all diagnostic checks. |
apparmor.baseDir |
"" |
AppArmor base directory override (e.g. /var/lib/snapd/apparmor for snap). Leave empty for the system default (/etc/apparmor). |
apparmor.includeSearchPaths |
[] |
Additional directories to search when resolving include directives. |
apparmor.parserConfigFile |
"" |
Path to an apparmor_parser configuration file. |
apparmor.apparmorParserPath |
"" |
Path to the apparmor_parser binary for syntax validation. |
apparmor.formatting.maxLineLength |
100 |
Maximum line length before rules are wrapped. Set to 0 to disable. |
apparmor.formatting.fileRuleStyle |
node-local |
Style for file rules: implicit (omit file keyword), explicit (include it), or node-local (preserve each rule's existing style). |
apparmor.formatting.sortLists |
true |
Sort parenthesised permission and flag lists alphabetically. |
apparmor.formatting.normalizeInclude |
true |
Rewrite legacy #include directives as include. |
apparmor.formatting.maxBlankLines |
1 |
Maximum consecutive blank lines to keep. Set to -1 to disable collapsing. |
Commands
| Command |
Description |
AppArmor: Restart Language Server |
Stop and restart the language server (useful after changing settings or reinstalling the server). |
Language Detection
The extension activates for files under any apparmor.d/ directory
(matching the pattern **/apparmor.d/**), which covers the standard
system profile directory /etc/apparmor.d/ and snap equivalents.
For any other file (e.g. a profile with no extension outside apparmor.d/),
set the language manually: click the language indicator in the VS Code status
bar and select AppArmor.
Issues and Contributing
| |