_apparmor
_apparmor
¶
AppArmor profile helpers for the per-container dnsmasq DNS tier.
terok-shield runs a per-container dnsmasq whose config/pid/log live under
the sandbox-live tasks/<project>/<task>/shield tree in the operator's
home. Distros that ship an enforcing AppArmor profile for
/usr/sbin/dnsmasq (Arch/Manjaro, the apparmor.d set) confine it to the
conventional server paths and deny that tree, so shield falls back to the
lookup tier. This module detects that confinement and points the operator at
the bundled installer that adds an addendum permitting the shield tree.
Detection is by file presence — unprivileged, no aa-status/root: an
AppArmor-enabled host that has dnsmasq and a stock dnsmasq profile but no
terok addendum is PROFILE_MISSING, and one whose addendum is an older
revision (marker present, current revision absent) is PROFILE_OUTDATED
— both point the operator at the installer. Install is delegated to
resources/apparmor/install_profile.sh — a short, auditable script run
with sudo bash (no compilation, just apparmor_parser -r).
AppArmorStatus
¶
Bases: Enum
Outcome of check_status.
NOT_APPLICABLE = 'not_applicable'
class-attribute
instance-attribute
¶
No AppArmor, no dnsmasq, or no dnsmasq profile — nothing to do.
PROFILE_MISSING = 'profile_missing'
class-attribute
instance-attribute
¶
dnsmasq is AppArmor-profiled but the terok addendum isn't installed.
PROFILE_OUTDATED = 'profile_outdated'
class-attribute
instance-attribute
¶
The terok addendum is installed but at an older revision whose rules no longer cover what shield writes — dnsmasq stays confined and DNS silently rides the lookup tier until the operator reinstalls (terok-ai/terok#1246).
OK = 'ok'
class-attribute
instance-attribute
¶
The terok addendum is installed at the current revision.
action_needed
property
¶
Whether this status calls for an operator install.
AppArmorCheckResult(status)
dataclass
¶
Structured outcome of check_status.
status
instance-attribute
¶
is_apparmor_enabled()
¶
Return True if the kernel has AppArmor enabled (sysfs Y).
dnsmasq_profile()
¶
Return the stock dnsmasq AppArmor profile present on this host, if any.
local_include_path(profile)
¶
Return the local/ include profile is extended through.
AppArmor profiles include local/<profile name> for site changes;
that file — not the distro profile — is where the managed block
lands, and what the interactive flow names before installing.
Source code in src/terok_sandbox/_util/_apparmor.py
check_status()
¶
Evaluate whether the dnsmasq AppArmor addendum is needed, stale, or current.
File-based and unprivileged. An AppArmor-enabled host with dnsmasq and
a stock dnsmasq profile is PROFILE_MISSING with no terok addendum,
PROFILE_OUTDATED when an older-revision addendum is present (the
marker but not the current revision), and OK at the current
revision; anything else is NOT_APPLICABLE.
Source code in src/terok_sandbox/_util/_apparmor.py
state_root()
¶
The sandbox-live root the addendum rules must permit.
Full precedence (env, config, default) via
sandbox_live_root, so
the rules name the tree the shield actually writes no matter which
frontend asks.
Source code in src/terok_sandbox/_util/_apparmor.py
install_script_path()
cached
¶
Return the path to the bundled install_profile.sh AppArmor installer.
Installation is delegated to this short, inspectable shell script —
run with sudo bash <path> <state_root> — so it can be cat-ed
and audited before the privilege escalation.
Source code in src/terok_sandbox/_util/_apparmor.py
render_addendum(state_root)
¶
Render the managed addendum block exactly as the installer writes it.
Same template, same substitution as install_profile.sh (a lone
@STATE_ROOT@ token, trailing slash stripped) — rendered on the
unprivileged side, where the operator's paths are known. What the
setup apparmor show option prints is therefore byte-identical to
what a subsequent sudo bash install appends to the profile.