← All articles

Seccomp and SELinux

How SELinux, seccomp, capabilities and namespaces constrain different parts of a container workload, with a Podman configuration and verification approach.

Suppose a containerised web service is compromised. The useful next question is specific: what can that process now read, modify, execute or contact? A container boundary alone does not answer it. Its mounts, identity, capabilities, network access and effective security policy all matter.

SELinux and seccomp address different parts of that question. Used together, they can narrow both the resources available to a workload and the kernel interfaces through which it operates. Their effectiveness comes from the actual restrictions, not from the presence of their names in a deployment file.

What is SELinux?

SELinux applies mandatory access policy to interactions between labelled subjects and objects. For a container workload, the process label and resource labels are part of the effective access-control configuration. Ordinary user/group permissions and other relevant checks still apply.

The policy is enforced by the host kernel. Installing SELinux utilities inside an image does not enable SELinux on the host. An image build is also not the place to install the host’s security policy or write the host’s enforcement controls. Those responsibilities belong to host administration and deployment.

The SELinux architecture documentation explains the relationship between labels, policy and enforcement. Container-specific labels and mount handling also depend on the runtime’s configuration.

What is seccomp?

Seccomp evaluates system-call entry against the installed filter. It can reduce the kernel attack surface exposed to the container process. It does not decide whether an arbitrary pathname is an authorised business resource, and it is not a complete container sandbox.

The distinction matters when reviewing an exception. A service may legitimately need file-opening calls while still being prohibited from reading another service’s files. A syscall restriction and an object-access rule answer different questions. See the seccomp article for filter actions, limitations and a small runnable example.

How do SELinux and seccomp work together?

Think of a workload’s authority as several constraints applied together:

ControlQuestion it helps answer
User and group permissionsWhich ordinary ownership-based accesses are permitted?
SELinux policy and labelsWhich subject-to-object interactions are authorised?
SeccompWhich system calls and supported argument patterns may enter the kernel?
Linux capabilitiesWhich selected privileged operations are available?
NamespacesWhich instances and views of kernel resources does the workload use?
Mount and network configurationWhich data and communication paths are exposed?

In Sovereign Fortress, SELinux Type Enforcement, Linux namespaces and restricted Linux capabilities are complementary parts of the runtime confinement design. Namespaces separate selected resource views, capability restrictions limit privileged operations, and SELinux policy governs access to labelled resources. The Linux namespaces and capabilities references describe the kernel mechanisms behind these controls.

These are complementary controls, not a guarantee that every combination is secure. Namespaces alter resource views and membership; they do not automatically express every desired access policy. Rootless execution reduces certain host privileges but does not remove the need to review mounts, credentials or kernel exposure.

Identity, resource access and kernel-interface restrictions jointly constrain a container workload.
Review the combined authority; these controls are complementary, not sequential stages.

A sensible policy review follows the workload’s responsibilities. A content-serving process may need read access to one content directory and a small amount of temporary storage. That does not imply a need to modify its content, read host credentials, contact a management API or change its own confinement.

Examples

The following is a configuration template for a reviewed Podman deployment on an SELinux-enforcing Linux host. It is not a universal command for an arbitrary image. Set container_image to a specific image digest whose runtime requirements you have verified.

podman run --rm --name confined-web \
  --user 10001:10001 \
  --read-only \
  --cap-drop=ALL \
  --security-opt=no-new-privileges \
  --security-opt=seccomp=./web-seccomp.json \
  --network=none \
  --tmpfs /tmp:rw,noexec,nosuid,nodev,size=16m \
  --volume ./site-content:/srv/content:ro,Z \
  "$container_image"

This deliberately starts without network connectivity. It is a local confinement exercise, not a published web service. The image must support that user, filesystem layout, temporary directory and seccomp profile. The content directory must be a disposable, dedicated test directory: :Z requests private SELinux relabelling and must not be applied casually to system or shared service directories. The Podman run reference documents these options.

The command references a workload-specific profile rather than supplying a misleading “secure for everything” JSON file. Build that profile from reviewed requirements and runtime testing. In particular, neither an allowing default with a few denials nor a copied syscall list should be represented as complete confinement without evidence.

On the host, read-only checks such as these help establish what was selected:

getenforce
podman inspect confined-web
ps -eZ

Run the inspection while the container is running, from a second terminal. Check the process and mount labels, user, capabilities, selected profile and exposed mounts. Metadata is useful evidence of configuration; it does not replace exercising the restricted paths.

Verify both useful work and denied access

A test plan should pair a functional requirement with a prohibited alternative:

Intended behaviourNegative check
Read approved contentAttempt to modify that content
Use the declared temporary directoryAttempt an undeclared persistent write
Perform supported processingExercise a deliberately forbidden syscall in a test workload
Remain isolated from the networkAttempt an external connection

An observed denial needs interpretation. A read-only mount may reject a write before SELinux does; a syscall filter may reject a call before another control becomes relevant. A failed operation therefore does not, by itself, prove which layer enforced the boundary. Identify the intended enforcement point and examine the corresponding evidence.

Test service restart, error handling and image updates as well as normal requests. A profile that permits startup but breaks certificate reload or log rotation is not operationally complete.

Conclusion

The objective is a workload with a clear and limited authority: enough access to do its job, with reviewed restrictions on its resources, privileges and kernel interface. This is also the question behind protecting the WAF itself. A security service deserves the same confinement analysis as the application it protects.

References

← Back to all articles

Contact Info

Send us a message

Tell us about your application, infrastructure or security requirements. All fields below are required.

Protected by our own security check.