Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From 2aeae85b1942d2bc12a7b827bdc896cdba3692eb Mon Sep 17 00:00:00 2001
From: Sean Dougherty <sdougherty@microsoft.com>
Date: Mon, 31 Aug 2026 16:30:00 +0000
Subject: [PATCH] container: Add CSI sidecar domain

Add an opt-in container_csi_sidecar_t domain for trusted CSI helper
containers that must connect to a privileged CSI driver socket. Include the
read-only sysfs and cgroup probes observed during helper startup.

Signed-off-by: Sean Dougherty <sdougherty@microsoft.com>
---
policy/modules/services/container.te | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/policy/modules/services/container.te b/policy/modules/services/container.te
index 4559fb5..f2d339f 100644
--- a/policy/modules/services/container.te
+++ b/policy/modules/services/container.te
@@ -173,6 +173,12 @@ optional_policy(`
container_domain_template(container_logreader)
typeattribute container_logreader_t container_system_domain, container_user_domain, container_net_domain;

+container_domain_template(container_csi_sidecar)
+typeattribute container_csi_sidecar_t container_system_domain, container_net_domain;
Comment thread
SeanDougherty marked this conversation as resolved.
+optional_policy(`
Comment thread
SeanDougherty marked this conversation as resolved.
+ kubernetes_container(container_csi_sidecar_t)
Comment thread
SeanDougherty marked this conversation as resolved.
+')
+
container_engine_domain_template(container_engine)
typeattribute container_engine_t container_engine_system_domain;
type container_engine_exec_t, container_engine_exec_type;
@@ -599,6 +605,15 @@ optional_policy(`
rpm_read_db(container_t)
')

+########################################
+#
+# CSI sidecar container local policy
+#
+
Comment thread
SeanDougherty marked this conversation as resolved.
+allow container_csi_sidecar_t spc_t:unix_stream_socket connectto;
Comment thread
SeanDougherty marked this conversation as resolved.
Comment thread
SeanDougherty marked this conversation as resolved.
+dev_read_sysfs(container_csi_sidecar_t)
+fs_read_cgroup_files(container_csi_sidecar_t)
+
########################################
#
# Log reader container local policy
--
2.45.4

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
From 1299975ad7844e95b95f90214801ed6c12ae9ea0 Mon Sep 17 00:00:00 2001
From: Sean Dougherty <sdougherty@microsoft.com>
Date: Mon, 31 Aug 2026 17:45:00 +0000
Subject: [PATCH] container: Allow log reader runtime probes

Fluent Bit probes VM overcommit and sysfs state during startup. Preserve the
read-only access available to the default container domain without granting
broad sysctl or sysfs access to container_logreader_t.

Signed-off-by: Sean Dougherty <sdougherty@microsoft.com>
---
policy/modules/services/container.te | 2 ++
1 file changed, 2 insertions(+)

diff --git a/policy/modules/services/container.te b/policy/modules/services/container.te
index e244da8..5402ec4 100644
--- a/policy/modules/services/container.te
+++ b/policy/modules/services/container.te
@@ -626,6 +626,8 @@ logging_read_audit_log(container_logreader_t)
logging_list_logs(container_logreader_t)
allow container_logreader_t logfile:lnk_file read_lnk_file_perms;
allow container_logreader_t container_log_t:file watch;
+kernel_read_vm_overcommit_sysctl(container_logreader_t)
+dev_read_sysfs(container_logreader_t)

optional_policy(`
systemd_read_journal_files(container_logreader_t)
--
2.51.0
8 changes: 7 additions & 1 deletion acl/SPECS/selinux-policy/selinux-policy.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Summary: SELinux policy
Name: selinux-policy
Version: %{refpolicy_major}.%{refpolicy_minor}
Release: 10%{?dist}
Release: 11%{?dist}
License: GPLv2
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand Down Expand Up @@ -82,6 +82,8 @@ Patch58: 0058-sysnetwork-Silence-sys_admin-denials.patch
Patch59: 0059-container-Drop-unqualified-etc-dir-filetrans-to-conta.patch
Patch60: 0060-container-Add-log-reader-domain.patch
Patch61: 0061-container-Allow-log-reader-to-map-journals.patch
Patch62: 0062-container-Add-CSI-sidecar-domain.patch
Patch63: 0063-container-Allow-log-reader-runtime-probes.patch
BuildRequires: bzip2
BuildRequires: checkpolicy >= %{CHECKPOLICYVER}
BuildRequires: m4
Expand Down Expand Up @@ -360,6 +362,10 @@ exit 0
selinuxenabled && semodule -nB
exit 0
%changelog
* Mon Aug 31 2026 Sean Dougherty <sdougherty@microsoft.com> - 2.20250213-11
- Add a confined CSI sidecar domain for privileged driver socket access.
- Allow confined container log readers to perform read-only runtime probes.
Comment thread
SeanDougherty marked this conversation as resolved.

* Fri Aug 21 2026 Sean Dougherty <sdougherty@microsoft.com> - 2.20250213-10
- Allow confined container log readers to map systemd journal files.

Expand Down
90 changes: 74 additions & 16 deletions acl/docs/selinux.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ a requirement described in this guide.
| --- | --- |
| General container workload | `container_t` |
| Read host logs without broad host privileges | `container_logreader_t` |
| Run a trusted CSI helper that connects to a privileged driver | `container_csi_sidecar_t` |
| Run a containerized KVM workload | `container_kvm_t` |
| Broadly privileged system container | `spc_t` |
| Broadly privileged rootless or user container | `spc_user_t` |
Expand All @@ -29,13 +30,14 @@ a narrowly scoped policy extension.

## Supported workload domains

The compiled ACL `selinux-policy-2.20250213-10` container policy contains five
The compiled ACL `selinux-policy-2.20250213-11` container policy contains six
workload process domains:

| Domain | Policy engine scope | MCS constrained | Intended use |
| --- | --- | --- | --- |
| `container_t` | System and user engines | ✅ Yes | Default confined container |
| `container_logreader_t` | System and user engines | ✅ Yes | Confined host-log collector |
| `container_csi_sidecar_t` | System engines | ✅ Yes | Trusted CSI helper container |
| `container_kvm_t` | System engines | ✅ Yes | Containerized KVM workload |
| `spc_t` | System engines | ❌ No | Privileged system container |
| `spc_user_t` | User engines | ❌ No | Privileged rootless or user container |
Expand Down Expand Up @@ -77,6 +79,13 @@ It additionally receives read-only mmap access to persistent files labeled
Inotify watch access applies only to `container_log_t`, not to every host log
type.

Unlike `container_t`, `container_csi_sidecar_t`, `container_kvm_t`, and
`spc_t`, this domain is intentionally not assigned the
`kubernetes_container_domain` attribute. It therefore does not receive that
attribute's management access to container runtime files under `/var/lib`,
container logs, and Kubernetes plugin files, which a read-only collector does
not require.

The domain intentionally does not grant:

- Write, append, create, delete, rename, or relabel access to host logs.
Expand Down Expand Up @@ -106,6 +115,53 @@ when a collector should not receive audit data.
The host log path must still be mounted into the container. Make the mount
read-only as defense in depth, and do not relabel the host log directory.

### `container_csi_sidecar_t`

`container_csi_sidecar_t` is the confined domain for trusted CSI helper
containers, such as a node-driver registrar or liveness probe, that must
connect to a privileged CSI driver through a Unix stream socket. It extends
the common container policy with the peer-domain `connectto` permission for
`spc_t` and read-only access to sysfs and cgroup files used by the helper
runtimes. It does not inherit the capabilities, general host access, or
unconfined attributes of `spc_t`.

The domain is assigned the `kubernetes_container_domain` attribute. It
therefore receives management access to container runtime files under
`/var/lib`, container logs, and Kubernetes plugin files in addition to the
permissions described above. This is broader than `container_logreader_t` and
is another reason to reserve the domain for trusted platform-managed CSI
helpers.

`spc_t` is shared by privileged system containers; it is not specific to CSI
drivers. The permission therefore reaches any `spc_t` Unix stream listener for
which the helper also has mount-namespace visibility, directory traversal,
socket-file access, and discretionary access. SELinux cannot express pod
membership in this rule, so select this domain only for trusted
platform-managed CSI helpers with narrowly mounted socket directories. Do not
use it for application workloads.

`spc_t` is also a Kubernetes container domain. Members of that attribute
already have a narrower connection path to `spc_t` for sockets labeled
`container_runtime_t`, such as runtime sockets under `/run`. The explicit
peer-domain rule is needed for the current CSI sockets labeled
`container_file_t` under `/var/lib/kubelet`; common container policy supplies
the required directory and socket-file access to that label. If a driver
instead exposes its socket through a path labeled `container_var_lib_t` or
`kubernetes_plugin_t`, socket-file access can fail before the peer-domain
`connectto` permission is evaluated. Validate the directory, socket-file, and
peer labels during rollout.

Runtime-assigned MCS categories do not narrow this connection because `spc_t`
is not MCS constrained and its sockets normally use `s0`. MCS still constrains
the helper's interactions with MCS-constrained domains and objects.

Policy support must reach every applicable node before a workload selects this
type. A type-only override in a multi-container pod may receive a different MCS
level from the pod sandbox and shared artifacts. Before enabling the domain in
a CSI manifest, validate coordinated MCS labeling for the driver, helpers,
projected files, and both CSI socket directions. Do not work around category
mismatches by using a static all-category level.

### `container_kvm_t`

`container_kvm_t` is the confined domain for containerized virtualization
Expand Down Expand Up @@ -159,16 +215,18 @@ purpose-built confined domain.

This table summarizes SELinux policy intent, not every individual permission.

| Capability | `container_t` | `container_logreader_t` | `container_kvm_t` | `spc_t` / `spc_user_t` |
| --- | --- | --- | --- | --- |
| Common container execution and storage | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
| Runtime-assigned MCS isolation | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
| Read types carrying `logfile` | ❌ No | ✅ Yes | ❌ No | ⚠️ Unconfined on stock ACL |
| Read and map persistent systemd journals | ❌ No | ✅ Yes | ❌ No | ⚠️ Unconfined on stock ACL |
| Read auditd-managed `auditd_log_t` files | ❌ No | ✅ Yes | ❌ No | ⚠️ Unconfined on stock ACL |
| KVM-specific policy | ❌ No | ❌ No | ✅ Yes | ❌ No — broad privileged access instead |
| Privileged-container policy class | ❌ No | ❌ No | ❌ No | ✅ Yes |
| SELinux-unconfined on stock ACL | ❌ No | ❌ No | ❌ No | ✅ Yes |
| Capability | `container_t` | `container_logreader_t` | `container_csi_sidecar_t` | `container_kvm_t` | `spc_t` / `spc_user_t` |
| --- | --- | --- | --- | --- | --- |
| Common container execution and storage | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
| Runtime-assigned MCS isolation | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
| Read types carrying `logfile` | ❌ No | ✅ Yes | ❌ No | ❌ No | ⚠️ Unconfined on stock ACL |
| Read and map persistent systemd journals | ❌ No | ✅ Yes | ❌ No | ❌ No | ⚠️ Unconfined on stock ACL |
| Read auditd-managed `auditd_log_t` files | ❌ No | ✅ Yes | ❌ No | ❌ No | ⚠️ Unconfined on stock ACL |
| Manage container runtime `/var/lib`, log, and Kubernetes plugin files | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes | ⚠️ Unconfined on stock ACL |
| Connect to privileged-container stream sockets | ⚠️ `container_runtime_t` sockets only | ❌ No | ⚠️ Any reachable `spc_t` listener | ⚠️ `container_runtime_t` sockets only | ✅ Yes |
| KVM-specific policy | ❌ No | ❌ No | ❌ No | ✅ Yes | ❌ No — broad privileged access instead |
| Privileged-container policy class | ❌ No | ❌ No | ❌ No | ❌ No | ✅ Yes |
| SELinux-unconfined on stock ACL | ❌ No | ❌ No | ❌ No | ❌ No | ✅ Yes |

## Selecting a domain

Expand Down Expand Up @@ -239,10 +297,10 @@ doing so collapses MCS isolation between them.

## MCS isolation

`container_t`, `container_logreader_t`, and `container_kvm_t` remain
`mcs_constrained_type` members. The container runtime assigns categories such
as `s0:c123,c456` so similarly typed containers cannot access each other's
objects.
`container_t`, `container_logreader_t`, `container_csi_sidecar_t`, and
`container_kvm_t` remain `mcs_constrained_type` members. The container runtime
assigns categories such as `s0:c123,c456` so similarly typed containers cannot
access each other's objects.

ACL builds the targeted policy in MCS mode. Standard host log file contexts
resolve to level `s0`, which is dominated by a normally categorized container
Expand Down Expand Up @@ -279,7 +337,7 @@ compiled policy is not a product support statement.

The shipped container runtime contexts file also contains an
`init_process` entry naming `container_init_t`. The compiled
`selinux-policy-2.20250213-10` ACL policy does not define that type, so it is
`selinux-policy-2.20250213-11` ACL policy does not define that type, so it is
not an available workload domain and must not be selected.

### File and object types
Expand Down
Loading