selinux module¶
Booleans
¶
Every SELinux boolean and its on/off state.
Commands:
getsebool -a
Returns:
dict[str, bool]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_booleans.py.
FileContext
¶
The SELinux context of one path, or None when unreadable.
Commands:
stat -c %C <path> || exit 0
Returns:
SeContext | None
Raises:
HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_file_context.py.
FileContextMapping
¶
The persistent fcontext mapping of one target, or None.
Commands:
set -o pipefail && semanage fcontext -n -l | (grep <target> || true)
Returns:
SeContext | None
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in
examples/modules/selinux/selinux_file_context_mapping.py.
Mode
¶
The SELinux runtime mode, config-file mode and loaded policy.
Commands:
sestatus
Returns:
ModeInfo
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_mode.py.
ModeInfo
¶
Attributes:
| Name | Type | Description |
|---|---|---|
mode |
str
|
The runtime mode -- |
config_mode |
str
|
The mode configured in |
policy |
str
|
The loaded policy name, e.g. |
Module
¶
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The policy module name (e.g. |
priority |
int
|
The module's priority in the store (400 is the default; higher priorities win when names collide). |
format |
str
|
The module's language format -- |
enabled |
bool
|
Whether the module is enabled; |
Modules
¶
The installed SELinux policy modules, with priority and state.
Commands:
semodule -lfull
Returns:
list[Module]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_modules.py.
PermissiveDomains
¶
The domains running in permissive mode despite global enforcement.
Commands:
semanage permissive -l
Returns:
list[str]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in
examples/modules/selinux/selinux_permissive_domains.py.
SEBoolean
¶
The status of one SELinux boolean as on or off.
Commands:
getsebool <boolean>
Returns:
str
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_se_boolean.py.
SELogin
¶
The SELinux user and range each Linux login maps to.
Commands:
semanage login -ln
Returns:
dict[str, SeLogin]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_se_login.py.
SEPort
¶
The SELinux type of one protocol/port pair, or the empty string.
Commands:
(sepolicy network -p <port> 2>/dev/null || true) | grep <protocol>
Returns:
str
Raises:
HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_se_port.py.
SEPorts
¶
The SELinux type labels of every defined port, by protocol.
Commands:
semanage port -ln
Returns:
dict[str, dict[int, str]]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_se_ports.py.
SEUser
¶
The SELinux user definitions: prefix, levels and allowed roles.
Commands:
semanage user -ln
Returns:
dict[str, SeUser]
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_se_user.py.
SeContext
¶
Attributes:
| Name | Type | Description |
|---|---|---|
user |
str
|
The SELinux user component (e.g. |
role |
str
|
The SELinux role component (e.g. |
type |
str
|
The SELinux type component (e.g. |
level |
str
|
The MLS/MCS level component (e.g. |
SeLogin
¶
Attributes:
| Name | Type | Description |
|---|---|---|
seuser |
str
|
The SELinux user the login maps to (e.g.
|
mls_range |
str
|
The MLS/MCS range of the mapping (e.g. |
service |
str
|
The PAM service column of newer semanage releases;
|
SeUser
¶
Attributes:
| Name | Type | Description |
|---|---|---|
prefix |
str
|
The labeling prefix SELinux user files are created
with (e.g. |
mls_level |
str
|
The MLS/MCS level of the user (e.g. |
mls_range |
str
|
The MLS/MCS range the user may enter (e.g.
|
roles |
list[str]
|
The SELinux roles the user may assume, in
listing order (e.g. |
SelinuxConfigFile
¶
The current content of the SELinux config file, or None when absent.
Commands:
test -e <path> && { printf '#reemote-selinuxconfig\n'; cat -- <path>; }
Returns:
str | None
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in examples/modules/selinux/selinux_config.py.
autorelabel
async
¶
Request a full filesystem relabel at the next boot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated autorelabel flag commands. |
Raises:
HostConnectionError
Examples:
Examples can be found in
examples/modules/selinux/selinux_autorelabel.py.
boolean
async
¶
boolean(
ctx: OpContext,
bool_name: str,
value: str,
persistent: bool = False,
**kwargs: Any,
) -> AsyncGenerator[Command]
Set one SELinux boolean to on or off.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
bool_name
|
str
|
Name of the SELinux boolean (e.g.
|
required |
value
|
str
|
Desired state of the boolean -- |
required |
persistent
|
bool
|
Whether to write the updated policy
( |
False
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated setsebool commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_boolean.py.
config
async
¶
config(
ctx: OpContext,
SELINUX: str | None = None,
SELINUXTYPE: str | None = None,
**kwargs: Any,
) -> AsyncGenerator[Command]
Set the boot-time mode and policy type in /etc/selinux/config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
SELINUX
|
str | None
|
The boot-time mode to ensure --
|
None
|
SELINUXTYPE
|
str | None
|
The policy type to ensure
(e.g. |
None
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated selinux config spool-and-install commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_config.py.
file_context
async
¶
file_context(
ctx: OpContext,
path: str,
se_type: str | None = None,
se_user: str | None = None,
se_role: str | None = None,
se_level: str | None = None,
**kwargs: Any,
) -> AsyncGenerator[Command]
Set the SELinux context components of one existing path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
path
|
str
|
The existing file or directory to relabel. |
required |
se_type
|
str | None
|
The SELinux type component (e.g.
|
None
|
se_user
|
str | None
|
The SELinux user component (e.g.
|
None
|
se_role
|
str | None
|
The SELinux role component (e.g.
|
None
|
se_level
|
str | None
|
The MLS/MCS level component (e.g.
|
None
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated chcon commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in
examples/modules/selinux/selinux_op_file_context.py.
file_context_mapping
async
¶
file_context_mapping(
ctx: OpContext,
target: str,
se_type: str | None = None,
present: bool = True,
**kwargs: Any,
) -> AsyncGenerator[Command]
Manage the persistent SELinux file context mapping of a target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
target
|
str
|
The target path expression the mapping matches (e.g.
|
required |
se_type
|
str | None
|
The SELinux type for the target
(e.g. |
None
|
present
|
bool
|
Whether the mapping should exist (added or modified) or be removed. Defaults to True. |
True
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated semanage fcontext commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in
examples/modules/selinux/selinux_op_file_context_mapping.py.
login
async
¶
login(
ctx: OpContext,
user: str,
seuser: str | None = None,
mls_range: str = "s0",
present: bool = True,
**kwargs: Any,
) -> AsyncGenerator[Command]
Map a Linux login to an SELinux user and MLS/MCS range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
user
|
str
|
The Linux login name to map (e.g. |
required |
seuser
|
str | None
|
The SELinux user to map to (e.g.
|
None
|
mls_range
|
str
|
The MLS/MCS range of the mapping (e.g.
|
's0'
|
present
|
bool
|
Whether the mapping should exist (added or modified) or be removed. Defaults to True. |
True
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated semanage login commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_login.py.
mode
async
¶
Set the SELinux runtime mode to enforcing or permissive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
mode
|
str
|
The runtime mode -- |
'enforcing'
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated setenforce commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_op_mode.py.
module
async
¶
module(
ctx: OpContext,
module_name: str,
state: str = "present",
source: str | None = None,
priority: int = 400,
**kwargs: Any,
) -> AsyncGenerator[Command]
Install, remove, enable or disable an SELinux policy module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
module_name
|
str
|
The policy module name (e.g.
|
required |
state
|
str
|
The wanted state -- |
'present'
|
source
|
str | None
|
Path of the compiled policy package
on the target host ( |
None
|
priority
|
int
|
The module priority for installation
( |
400
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated semodule commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_module.py.
permissive_domain
async
¶
permissive_domain(
ctx: OpContext,
domain: str,
present: bool = True,
**kwargs: Any,
) -> AsyncGenerator[Command]
Add or remove a permissive domain exemption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
domain
|
str
|
The SELinux domain type to exempt (e.g.
|
required |
present
|
bool
|
Whether the domain should be permissive (added) or enforcing again (removed). Defaults to True. |
True
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated semanage permissive commands. |
Raises:
CommandNotFoundError, HostConnectionError
Examples:
Examples can be found in
examples/modules/selinux/selinux_permissive_domain.py.
port
async
¶
port(
ctx: OpContext,
protocol: str,
port_num: int,
se_type: str | None = None,
present: bool = True,
**kwargs: Any,
) -> AsyncGenerator[Command]
Manage the SELinux type label of one protocol/port pair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
protocol
|
str
|
The protocol -- |
required |
port_num
|
int
|
The port number to label. |
required |
se_type
|
str | None
|
The SELinux port type (e.g.
|
None
|
present
|
bool
|
Whether the label should exist (added or modified) or be removed. Defaults to True. |
True
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated semanage port commands. |
Raises:
CommandNotFoundError, HostConnectionError, ValueError
Examples:
Examples can be found in examples/modules/selinux/selinux_port.py.
restorecon
async
¶
restorecon(
ctx: OpContext,
path: str,
recurse: bool = True,
force: bool = False,
**kwargs: Any,
) -> AsyncGenerator[Command]
Relabel a path tree from the SELinux file context database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
OpContext
|
Execution context for the operation. |
required |
path
|
str
|
The file or directory to relabel. |
required |
recurse
|
bool
|
Relabel the whole directory tree
( |
True
|
force
|
bool
|
Reset even user-customized context parts
( |
False
|
**kwargs
|
Any
|
Additional keyword arguments. |
{}
|
Yields:
| Name | Type | Description |
|---|---|---|
Command |
AsyncGenerator[Command]
|
Generated restorecon commands. |
Raises:
None
Examples:
Examples can be found in
examples/modules/selinux/selinux_restorecon.py.
row (baseline parity); empty or
malformed output reads as the empty string.Booleansis the original
whole-table sibling:getsebool -aparsed into a name → bool mapping
(True only foron`), one read for a full boolean audit.
FileContext takes a path and runs stat -c %C <path> || exit 0,
splitting the user:role:type:level label into the shared SeContext
TypedDict; an unlabelled filesystem (?) or a missing path reads None
(the baseline's None-on-absent). FileContextMapping takes a target expression
and greps the local-only fcontext database
(set -o pipefail && semanage fcontext -n -l | (grep '^<target>' || true))
for the single matching row's trailing context, returning the same
SeContext shape — the persistent rule a relabel would apply, not the
label a file carries now. Deliberate deviation from the baseline: no mapping
reads None rather than {}, the house None-on-absent convention. A
missing semanage exits 127, reported as
CommandNotFoundError.
SEPorts runs semanage port -ln and keeps a protocol → port → type map,
expanding ranges (9000-9010) to individual ports and skipping the
unreserved_port_t catch-all (baseline parity); the two optional filter
arguments are the reemote enhancement — protocol keeps one protocol's
table, se_type keeps only ports carrying one type label, so a port audit
is one filtered read. SEPort takes a protocol and port and runs
(sepolicy network -p <port> 2>/dev/null || true) | grep <protocol>,
keeping the first row's type only when both the specific and the generic
range row are present — a port covered by a generic range alone reads as
the empty string (the baseline's gate). The || true tolerates a host without
sepolicy (policycoreutils-dev is not stock).
Mode is the original foundation every SELinux decision starts from:
sestatus parsed into a ModeInfo record — mode (runtime: enforcing,
permissive or disabled), config_mode (the boot setting from
/etc/selinux/config) and policy (the loaded policy name, e.g.
targeted). Keeping runtime beside config tells "enforcing now but
permissive after reboot" apart from a fully enforcing host; a disabled
subsystem reads mode="disabled" with empty config/policy fields.
SelinuxConfigFile is the raw-content fact behind selinux.config: it
reads /etc/selinux/config's whole text (test -e + marker + cat),
returning the file as a str — None when absent, "" when present but
empty, the marker keeping the two apart. It exists because a config edit
must preserve the comments, blank lines and ordering the stock file ships
with: rebuilding the text from Mode's parsed config_mode would destroy
them (the OpenrcConfigFile pattern).
SELogin runs semanage login -ln and keys the rows by Linux login name,
keeping seuser, mls_range and the service column newer releases add
(* when absent) as SeLogin entries; the __default__ fallback row is
kept like any other. SEUser runs semanage user -ln and keys the rows by
SELinux user name, keeping prefix, mls_level, mls_range and the
variable-length roles tail as SeUser entries — read it beside
SELogin to audit the full confined-user chain. Modules runs
semodule -lfull (which, unlike -l, shows disabled instances and
lower-priority duplicates) and keeps a list of Module instances —
name, priority, format (pp/cil), enabled — in listing order;
modern semodule no longer prints versions, so priority/format/state are
the modern equivalents of the proposal's name-and-version shape.
PermissiveDomains runs semanage permissive -l and keeps the domain
names as a deduplicated list, skipping the builtin-types heading — the
domains exempted from enforcement despite a globally enforcing policy.
Operations¶
Operations live in namespace modules so a deploy reads selinux.boolean,
mirroring the baseline's API. Every operation is an async generator with the
same fixed signature:
async def operation(ctx: OpContext, *args, **kwargs) -> AsyncGenerator[Command, None]:
It awaits facts via ctx.facts, sets ctx.changed and ctx.reason where
it decides a change is needed, and yields one descriptor per command that
would mutate the host. Every operation here writes root-owned kernel or
policy state, so flag the request sudo=True (or su=True/doas=True).
selinux.boolean (baseline parity) sets one boolean to on/off,
idempotent on SEBoolean — the check-before-executing the enhancement
asked for falls out of the fact-driven model, sparing the expensive
setsebool -P policy rewrite on an unchanged boolean. persistent=True
adds -P. The baseline's Boolean enum is dropped: value is the plain
on/off string, anything else raises ValueError.
selinux.file_context (baseline parity, enhanced to the full context)
relabels one existing path with chcon: each of se_type, se_user,
se_role, se_level is optional, at least one must be given, and only
the components differing from the FileContext fact are yielded. The
label is runtime-only — a relabel reverts it to the database rule, which
is selinux.file_context_mapping's job (baseline parity): present=True
adds (semanage fcontext -a) or modifies (-m) the persistent rule for a
target expression, present=False deletes it (-d), idempotent on
FileContextMapping. selinux.restorecon (original) is the documented
remedy for both limitations: it reapplies the database to a tree
(restorecon [-R] [-F] <path>). It is deliberately stateless — no
fact compares a whole tree against the database — so every request yields
and reports a change; restorecon itself only writes labels that differ.
selinux.port (baseline parity, enhanced with modify) labels a
protocol/port pair: present=True adds an unlabelled port
(semanage port -a) or modifies a differently-labelled one in place
(-m) — the update scenario the baseline's add/remove-only operation could not
express — and present=False deletes the label (-d). Idempotence
dispatches on tooling: the SEPort fact when sepolicy is installed,
otherwise the SEPorts table.
selinux.mode (original) sets the runtime enforcing state with
setenforce, idempotent on Mode; it never touches
/etc/selinux/config (the boot setting is selinux.config's job)
and raises ValueError on a disabled subsystem — setenforce cannot
enable SELinux, the transition needs the config edit, autorelabel and a
reboot. selinux.config (original) ensures the boot-time settings in
/etc/selinux/config: SELINUX (enforcing/permissive/disabled) and
SELINUXTYPE (any installed policy's name), each optional — None leaves
that key untouched, both None raises ValueError. A member of the
spool-and-install write family, it supersedes the files.edit +
files.move recipe the example used to demonstrate: the file's text is
read with SelinuxConfigFile, every existing assignment of each requested
key is dropped (commented ones included — replacement semantics, so no
contradictory commented line survives) and KEY=value is appended
unquoted, the stock convention; the new text is scp'd to a /tmp spool
named after the managed path's sha1 (deterministic across phases) and
installed by an elevated sh -c that copies it over the file, chmods it
0644 and removes the spool — the transfer never elevates, the install
always does. A key whose only assignment already is the wanted line keeps
the file byte-for-byte, so a matching config is a no-op; the edit takes
effect at the next reboot, and switching a disabled subsystem to
enforcing additionally needs selinux.autorelabel before that reboot.
selinux.login (original) manages the Linux-user → SELinux-user
mapping (semanage login -a/-m/-d), idempotent on SELogin comparing
both user and range (the service column is never managed).
selinux.module (original) manages policy modules through a four-state
machine — present installs (semodule -X <priority> -i <source>) or
re-enables, absent removes (-r), enabled/disabled flip an
installed instance (-e/-d) — idempotent on Modules; the parameter is
named module_name because op() reserves name for the request label
(the baseline's bool_name precedent), and enabling/disabling an uninstalled
module raises ValueError in prepare. selinux.permissive_domain
(original) adds or removes one domain from the permissive list
(semanage permissive -a/-d), idempotent on PermissiveDomains — the
surgical alternative to global permissive mode when troubleshooting one
service. selinux.autorelabel (original) creates the /.autorelabel
marker (touch /.autorelabel) scheduling a full-system relabel at the
next boot, idempotent on the marker's existence — the heavy remedy for a
disabled-to-enabled transition or severely corrupted contexts, with a
clear warning: the relabel can take many minutes and needs a reboot this
operation does not trigger.
Example¶
The read-only fact-gathering scripts under
examples/modules/selinux/ gather one
fact each over gather_fact on the shared inventory.json's CentOS
hosts (the dnf convention — every target is an SELinux host, and the
is_centos guard filters the host list before the fan-out):
selinux_se_boolean.py, selinux_booleans.py,
selinux_file_context.py, selinux_file_context_mapping.py,
selinux_se_ports.py (full table plus a protocol/type-filtered gather),
selinux_se_port.py, selinux_mode.py, selinux_se_login.py,
selinux_se_user.py, selinux_modules.py and
selinux_permissive_domains.py.
The operation scripts beside them demonstrate selinux.boolean
(selinux_boolean.py), selinux.file_context
(selinux_op_file_context.py, type-only twice plus a full-context
request), selinux.file_context_mapping
(selinux_op_file_context_mapping.py, composed with restorecon),
selinux.port (selinux_port.py), selinux.mode (selinux_op_mode.py),
selinux.login (selinux_login.py), selinux.module
(selinux_module.py), selinux.permissive_domain
(selinux_permissive_domain.py, a full add → no-op → remove cycle),
selinux.restorecon (selinux_restorecon.py, the stateless contract),
selinux.autorelabel (selinux_autorelabel.py) and selinux.config
(selinux_config.py, the boot-time settings in one request — it used to
be the files.edit spool-and-install recipe the operation superseded).
All are rendered on the
selinux examples page.
--->