Project 5: Container SELinux Sandbox Lab

Build a lab that demonstrates how SELinux isolates containers using types and MCS categories, including labeled volumes and denial analysis.

Quick Reference

Attribute Value
Difficulty Level 3: Advanced
Time Estimate 2-3 weeks
Main Programming Language Shell + Python
Alternative Programming Languages Go, Rust
Coolness Level Level 5
Business Potential 2
Prerequisites Containers basics (podman/docker), Projects 1-2
Key Topics svirt, MCS categories, container_t, volume labeling, isolation

1. Learning Objectives

By completing this project, you will:

  1. Explain how SELinux labels isolate containers and volumes.
  2. Use MCS categories to enforce container separation.
  3. Build a reproducible lab to demonstrate allow/deny behavior.
  4. Diagnose container AVC denials and implement correct fixes.
  5. Understand how container runtimes integrate with SELinux.

2. All Theory Needed (Per-Concept Breakdown)

Container SELinux Types and sVirt

Fundamentals

Container runtimes on SELinux-enabled systems use specific process and file types to isolate containers from the host and from each other. A typical container process runs in a domain such as container_t, and container files use types such as container_file_t or container_var_lib_t. The sVirt model labels each container with unique categories that act like per-VM compartments. This makes it possible to run multiple containers with the same process type while still preventing them from accessing each other’s files. Understanding these types and how sVirt works is essential to building a container isolation lab.

Deep Dive into the concept

sVirt is the SELinux-based isolation model originally used for virtual machines and later adapted to containers. It works by labeling each container process with a type (container_t) and a unique set of MCS categories (e.g., s0:c123,c456). The container’s files are labeled with the same categories, so the process can access only its own files. This is a form of Mandatory Access Control that does not depend on Unix user IDs. The policy allows container_t to access container_file_t only when categories match. This is the critical detail: even if two containers run the same image, their category sets differ, so they cannot access each other’s volumes.

Container runtimes like Podman or Docker integrate with SELinux by setting labels on the container process and mount points. When a container is started, the runtime assigns a random MCS category set and applies it to the process and mounts. You can see this with ps -eZ and ls -Z. The runtime also applies special mount labels when you use :Z or :z on volume mounts. :Z gives a private label (unique categories), while :z allows shared access by relabeling with a shared category. Understanding this distinction is crucial for debugging volume access issues.

The container SELinux types are part of a targeted policy. container_t is allowed to access container_file_t and certain device and network resources. But it is denied access to host-labeled files (like etc_t or var_log_t) unless explicit relabeling occurs. This is why a containerized app may fail to read host files even if it runs as root inside the container. The root user inside the container is still confined by SELinux domain rules. This is a powerful demonstration of SELinux’s MAC model.

Your lab should show these rules explicitly. For example, mount a host directory into a container without relabeling and observe the denial. Then mount it with :Z and show that access is permitted. The lab should also show cross-container isolation: create two containers, label their volumes with unique categories, and demonstrate that each container cannot read the other’s volume even with broad Unix permissions. This demonstrates MCS enforcement in practice.

Additional operational notes on Container SELinux Types and sVirt: In real systems, this concept interacts with policy versions, distribution defaults, and local overrides. Always record the exact policy version and runtime toggles when diagnosing behavior, because the same action can be allowed on one host and denied on another. When you change configuration related to this concept, capture before/after evidence (labels, logs, and outcomes) so you can justify the change, detect regressions, and roll it back if needed. Treat every tweak as a hypothesis: change one variable, re-run the same action, and compare results against a known baseline. This makes debugging repeatable and keeps your fixes defensible.

From a design perspective, treat Container SELinux Types and sVirt as an invariant: define what success means, which data proves it, and what failure looks like. Build tooling that supports dry-run mode and deterministic fixtures so you can validate behavior without risking production. This also makes the concept teachable to others. Finally, connect the concept to security and performance trade-offs: overly broad changes reduce security signal, while overly strict changes create operational friction. Good designs surface these trade-offs explicitly so operators can make safe decisions.

How this fit on projects

Container types and sVirt are central to §3.2 and §3.7, and they are referenced in P10-mls-mcs-classification-demo-system.md for category reasoning.

Definitions & key terms

  • container_t -> default SELinux domain for containers
  • sVirt -> SELinux model for isolating VMs/containers
  • MCS categories -> category labels used for isolation
  • :Z / :z -> volume relabel flags for private/shared

Mental model diagram

container_t:s0:c123,c456  <->  container_file_t:s0:c123,c456

How it works (step-by-step, with invariants and failure modes)

  1. Runtime assigns MCS categories to container process.
  2. Volumes are labeled with matching categories.
  3. SELinux checks both type and category during access.
  4. Access allowed only if categories match.

Invariants: type and category must both match for access. Failure modes: volumes not relabeled, categories mismatched.

Minimal concrete example

$ podman run -v /srv/data:/data:Z docker.io/library/busybox ls -Z /data

Common misconceptions

  • “Root in a container bypasses SELinux.” -> It does not.
  • “All containers can access shared host volumes.” -> Only if labeled with shared categories.

Check-your-understanding questions

  1. What does :Z do to a volume label?
  2. Why can two container_t processes be isolated?
  3. What happens if you mount a host directory without relabeling?

Check-your-understanding answers

  1. It relabels the volume with a private MCS category set.
  2. They have different MCS categories, so access is blocked.
  3. SELinux denies access because host file types are not permitted.

Real-world applications

  • Multi-tenant container platforms.
  • Isolating untrusted workloads on shared hosts.

Where you’ll apply it

References

  • Red Hat container SELinux documentation
  • “SELinux by Example” (MCS sections)

Key insights

SELinux container isolation is enforced by both type and category, not by container runtime alone.

Summary

Containers are confined by SELinux types and MCS categories; volume labeling is the critical operational detail.

Homework/Exercises to practice the concept

  1. Start two containers and compare their MCS categories.
  2. Mount a directory without relabeling and observe the denial.
  3. Repeat with :Z and confirm access.

Solutions to the homework/exercises

  1. Use ps -eZ | grep container to see category sets.
  2. Access denied because host labels do not match container policy.
  3. :Z relabels volumes to match the container categories.

MCS Categories and Isolation Semantics

Fundamentals

MCS (Multi-Category Security) is a simplified form of MLS used to isolate workloads by category labels. Categories are expressed as sets, such as c123,c456, and access is allowed only when the subject’s categories dominate the object’s categories. In container policy, the rule is typically that categories must be equal. This makes MCS a practical isolation mechanism for containers without requiring full MLS complexity. Your lab should include exercises that show how category mismatch causes access denials even when types match.

Deep Dive into the concept

MCS extends the SELinux label by adding categories to the level field. The label s0:c123,c456 means sensitivity level s0 and categories c123 and c456. In targeted policy, sensitivity levels are usually the same, so categories provide the isolation dimension. The kernel compares categories during access decisions. For container policy, the rules are typically written so that subjects and objects must have the exact same categories, creating strict isolation. This is different from full MLS, where dominance rules allow “read down” and “write up”. MCS is simpler and therefore easier to apply to containers.

The container runtime allocates MCS categories from a pool, ensuring that each container gets a unique set. The categories are then applied to process labels and volume labels. When you mount a volume with :Z, the runtime relabels the directory with the container’s categories. With :z, the runtime uses a shared category set, allowing multiple containers to access the same volume. This is a deliberate trade-off: :z is convenient but weakens isolation. Your lab should demonstrate this by showing that two containers with a shared :z volume can both read it, while a :Z volume is private.

The MCS system also has limits. Category space is finite, so long-running systems can exhaust available categories if containers are created and destroyed frequently. Runtimes manage this by recycling categories, but it is still possible to see overlaps over time. Your lab can include a cautionary note about this and encourage operators to monitor category usage. Another nuance is that MCS labels on files can be lost if files are copied without preserving xattrs, leading to s0 without categories. This results in denials when a container tries to access the file. A good lab should include a “label loss” scenario to show why preserving xattrs matters.

Operational expansion for MCS Categories and Isolation Semantics: In real systems, the behavior you observe is the product of policy, labels, and runtime state. That means your investigation workflow must be repeatable. Start by documenting the exact inputs (contexts, paths, users, domains, ports, and the action attempted) and the exact outputs (audit events, error codes, and any policy query results). Then, replay the same action after each change so you can attribute cause and effect. When the concept touches multiple subsystems, isolate variables: change one label, one boolean, or one rule at a time. This reduces confusion and prevents accidental privilege creep. Use staging environments or fixtures to test fixes before deploying them widely, and always keep a rollback path ready.

To deepen understanding, connect MCS Categories and Isolation Semantics to adjacent concepts: how it affects policy decisions, how it appears in logs, and how it changes operational risk. Build small verification scripts that assert the expected outcome and fail loudly if the outcome diverges. Over time, these scripts become a regression suite for your SELinux posture. Finally, treat the concept as documentation-worthy: write down the invariants it guarantees, the constraints it imposes, and the exact evidence that proves it works. This makes future debugging faster and creates a shared mental model for teams.

How this fit on projects

Container types and sVirt are central to §3.2 and §3.7, and they are referenced in P10-mls-mcs-classification-demo-system.md for category reasoning.

Further depth on MCS Categories and Isolation Semantics: In production environments, this concept is shaped by policy versions, automation layers, and distro-specific defaults. To keep reasoning consistent, capture a minimal evidence bundle every time you analyze behavior: the policy name/version, the exact labels or contexts involved, the command that triggered the action, and the resulting audit event. If the same action yields different decisions on two hosts, treat that as a signal that a hidden variable changed (boolean state, module priority, label drift, or category range). This disciplined approach prevents trial-and-error debugging and makes your conclusions defensible.

Operationally, build a short checklist for MCS Categories and Isolation Semantics: verify prerequisites, verify labels or mappings, verify policy query results, then run the action and confirm the expected audit outcome. Track metrics that reflect stability, such as the count of denials per hour, the number of unique denial keys, or the fraction of hosts in compliance. When you must change behavior, apply the smallest change that can be verified (label fix before boolean, boolean before policy). Document the rollback path and include a post-change validation step so the system returns to a known-good state.

Definitions & key terms

  • container_t -> default SELinux domain for containers
  • sVirt -> SELinux model for isolating VMs/containers
  • MCS categories -> category labels used for isolation
  • :Z / :z -> volume relabel flags for private/shared

Mental model diagram

container_t:s0:c123,c456  <->  container_file_t:s0:c123,c456

How it works (step-by-step, with invariants and failure modes)

  1. Runtime assigns MCS categories to container process.
  2. Volumes are labeled with matching categories.
  3. SELinux checks both type and category during access.
  4. Access allowed only if categories match.

Invariants: type and category must both match for access. Failure modes: volumes not relabeled, categories mismatched.

Minimal concrete example

$ podman run -v /srv/data:/data:Z docker.io/library/busybox ls -Z /data

Common misconceptions

  • “Root in a container bypasses SELinux.” -> It does not.
  • “All containers can access shared host volumes.” -> Only if labeled with shared categories.

Check-your-understanding questions

  1. What does :Z do to a volume label?
  2. Why can two container_t processes be isolated?
  3. What happens if you mount a host directory without relabeling?

Check-your-understanding answers

  1. It relabels the volume with a private MCS category set.
  2. They have different MCS categories, so access is blocked.
  3. SELinux denies access because host file types are not permitted.

Real-world applications

  • Multi-tenant container platforms.
  • Isolating untrusted workloads on shared hosts.

Where you’ll apply it

References

  • Red Hat container SELinux documentation
  • “SELinux by Example” (MCS sections)

Key insights

SELinux container isolation is enforced by both type and category, not by container runtime alone.

Summary

Containers are confined by SELinux types and MCS categories; volume labeling is the critical operational detail.

Homework/Exercises to practice the concept

  1. Start two containers and compare their MCS categories.
  2. Mount a directory without relabeling and observe the denial.
  3. Repeat with :Z and confirm access.

Solutions to the homework/exercises

  1. Use ps -eZ | grep container to see category sets.
  2. Access denied because host labels do not match container policy.
  3. :Z relabels volumes to match the container categories.

Volume Labeling and Mount Semantics

Fundamentals

Volumes are the most common source of SELinux container issues. When you mount a host directory into a container, the labels on that directory determine whether the container can access it. Using the :Z or :z mount option tells the runtime to relabel the directory. Without relabeling, access is often denied because host file types are not permitted for container_t. This project must demonstrate correct labeling and how to diagnose failures.

Deep Dive into the concept

A container volume is a bind mount from the host filesystem into the container’s namespace. SELinux enforces access on the host kernel, so the host labels still matter. If you mount /srv/data into a container without relabeling, and that path is labeled default_t or var_t, the container_t domain likely lacks permission. The runtime can relabel the directory to container_file_t and apply MCS categories with :Z. This is a convenience, but it is also a powerful action: it changes labels on host files, which may affect host processes. This is why container runtimes require explicit opt-in to relabel volumes.

The :Z option applies a unique label and categories, making the volume private to one container. The :z option applies a shared label so multiple containers can access the same data. Both options are implemented by the runtime using chcon or setfilecon under the hood. The :Z option is safer for isolation, while :z is necessary for shared data (for example, in sidecar patterns). Your lab should include both scenarios and show the difference in labels.

There is also the concept of read-only volumes. SELinux enforces access control beyond Unix permissions, but you should still use :ro when possible because it narrows the access even if SELinux allows more. The lab should include a read-only mount case and show that writes are blocked by DAC even when SELinux would allow. This helps users understand the layered security model.

Diagnosing volume labeling issues involves inspecting the host path label (ls -Z /srv/data) and the container process label (ps -eZ). If they do not match, access fails. Tools like ausearch will show AVC denials that mention tcontext with the host label. Your tool should guide the user through this and provide the exact podman or docker command to fix the issue. This turns a common pain point into a structured learning experience.

Operational expansion for se chcon -t container_file_t -l s0:c1,c2 /srv/data then access from another container.: In real systems, the behavior you observe is the product of policy, labels, and runtime state. That means your investigation workflow must be repeatable. Start by documenting the exact inputs (contexts, paths, users, domains, ports, and the action attempted) and the exact outputs (audit events, error codes, and any policy query results). Then, replay the same action after each change so you can attribute cause and effect. When the concept touches multiple subsystems, isolate variables: change one label, one boolean, or one rule at a time. This reduces confusion and prevents accidental privilege creep. Use staging environments or fixtures to test fixes before deploying them widely, and always keep a rollback path ready.

To deepen understanding, connect se chcon -t container_file_t -l s0:c1,c2 /srv/data then access from another container. to adjacent concepts: how it affects policy decisions, how it appears in logs, and how it changes operational risk. Build small verification scripts that assert the expected outcome and fail loudly if the outcome diverges. Over time, these scripts become a regression suite for your SELinux posture. Finally, treat the concept as documentation-worthy: write down the invariants it guarantees, the constraints it imposes, and the exact evidence that proves it works. This makes future debugging faster and creates a shared mental model for teams.

How this fit on projects

MCS categories are used in §3.2 and §3.7. This concept prepares you for P10-mls-mcs-classification-demo-system.md.

Further depth on se chcon -t container_file_t -l s0:c1,c2 /srv/data then access from another container.: In production environments, this concept is shaped by policy versions, automation layers, and distro-specific defaults. To keep reasoning consistent, capture a minimal evidence bundle every time you analyze behavior: the policy name/version, the exact labels or contexts involved, the command that triggered the action, and the resulting audit event. If the same action yields different decisions on two hosts, treat that as a signal that a hidden variable changed (boolean state, module priority, label drift, or category range). This disciplined approach prevents trial-and-error debugging and makes your conclusions defensible.

Operationally, build a short checklist for se chcon -t container_file_t -l s0:c1,c2 /srv/data then access from another container.: verify prerequisites, verify labels or mappings, verify policy query results, then run the action and confirm the expected audit outcome. Track metrics that reflect stability, such as the count of denials per hour, the number of unique denial keys, or the fraction of hosts in compliance. When you must change behavior, apply the smallest change that can be verified (label fix before boolean, boolean before policy). Document the rollback path and include a post-change validation step so the system returns to a known-good state.

Definitions & key terms

  • MCS -> Multi-Category Security
  • categories -> label components used for isolation
  • dominance -> comparison rule for access
  • shared volume -> :z labeled volume

Mental model diagram

container A: s0:c1,c2  -> data A: s0:c1,c2  (allowed)
container B: s0:c3,c4  -> data A: s0:c1,c2  (denied)

How it works (step-by-step, with invariants and failure modes)

  1. Runtime assigns categories to container process.
  2. Volumes are relabeled with the same categories.
  3. SELinux compares categories on access.
  4. Access allowed only when categories match.

Invariants: category match required for container policy. Failure modes: labels lost, shared volume accidentally used.

Minimal concrete example

$ ps -eZ | grep container
system_u:system_r:container_t:s0:c123,c456  3123 ? 00:00:00 conmon

Common misconceptions

  • “MCS is the same as MLS.” -> MCS is a simplified category-only model.
  • “Categories are only for containers.” -> They are a general SELinux feature.

Check-your-understanding questions

  1. What does a category set represent?
  2. Why does :z weaken isolation?
  3. What happens if a container accesses a file without categories?

Check-your-understanding answers

  1. A set of tags used to isolate workloads.
  2. It uses a shared category, allowing multiple containers to access the same data.
  3. Access is denied because categories do not match.

Real-world applications

  • Multi-tenant container environments.
  • Shared storage with controlled access.

Where you’ll apply it

References

  • Red Hat SELinux documentation on MCS
  • “SELinux by Example” (MCS chapters)

Key insights

Categories are the isolation layer that make containers safe on a shared host.

Summary

MCS labels enforce container separation; category mismatches lead to deterministic denials.

Homework/Exercises to practice the concept

  1. Start a container and note its category labels.
  2. Relabel a directory with a different category and attempt access.
  3. Demonstrate shared volume access with :z.

Solutions to the homework/exercises

  1. ps -eZ shows the categories.
  2. Use chcon -t container_file_t -l s0:c1,c2 /srv/data then access from another container.
  3. podman run -v /shared:/data:z from two containers and confirm both can read.

3. Project Specification

3.1 What You Will Build

A reproducible container SELinux lab that demonstrates:

  • Container process labels and MCS categories
  • Volume relabeling with :Z and :z
  • Isolation between two containers
  • AVC denial collection and remediation steps

3.2 Functional Requirements

  1. Lab Scripts: Provide scripts to start containers and collect labels.
  2. Isolation Demo: Show cross-container access denial.
  3. Volume Demo: Show :Z vs :z behavior.
  4. Denial Analysis: Capture AVCs and explain fixes.
  5. Documentation: Provide step-by-step lab guide.

3.3 Non-Functional Requirements

  • Repeatability: Lab should be deterministic with fixed container images.
  • Safety: Use disposable paths under /srv/selinux-lab.
  • Clarity: Provide clear expected outputs.

3.4 Example Usage / Output

$ ./lab/start.sh
Container A label: system_u:system_r:container_t:s0:c123,c456
Container B label: system_u:system_r:container_t:s0:c789,c101

$ ./lab/test_isolation.sh
Attempt A -> B data: DENIED (expected)

3.5 Data Formats / Schemas / Protocols

Lab result report (text):

container_a_label=...
container_b_label=...
volume_mode=Z
isolation_result=denied

3.6 Edge Cases

  • Host filesystem without SELinux xattr support
  • Runtime configured without SELinux support
  • Labels lost due to improper copy operations

3.7 Real World Outcome

3.7.1 How to Run (Copy/Paste)

./lab/setup.sh
./lab/start_containers.sh
./lab/run_tests.sh

3.7.2 Golden Path Demo (Deterministic)

Use a fixed container image digest and pre-created directories under /srv/selinux-lab. Use seeded category assignments if the runtime supports it, otherwise record the categories in output for verification.

3.7.3 CLI Transcript (Success and Failure)

$ ./lab/run_tests.sh
TEST: cross-container read
Result: DENIED (expected)
Exit code: 0

$ ./lab/run_tests.sh --no-relabel
TEST: container volume access
Result: DENIED (expected)
Exit code: 0

4. Solution Architecture

4.1 High-Level Design

Lab Scripts -> Container Runtime -> SELinux Labels -> AVC Logs

4.2 Key Components

Component Responsibility Key Decisions
Lab scripts Start containers, mount volumes Use podman for SELinux integration
Label inspector Capture labels Use ps -eZ and ls -Z
Test harness Run access tests Simple shell commands
Report generator Summarize results Text report for determinism

4.3 Data Structures (No Full Code)

lab_state:
  containers: [name, pid, label]
  volumes: [path, label, mode]

4.4 Algorithm Overview

Key Algorithm: Isolation Test

  1. Identify container A and B labels.
  2. Write a file in A’s volume.
  3. Attempt to read it from B.
  4. Expect denial.

Complexity Analysis:

  • Time: O(1) per test
  • Space: O(1)

5. Implementation Guide

5.1 Development Environment Setup

sudo dnf install -y podman selinux-policy

5.2 Project Structure

lab/
├── setup.sh
├── start_containers.sh
├── run_tests.sh
├── inspect_labels.sh
└── README.md

5.3 The Core Question You’re Answering

“How does SELinux isolate containers on the same host?”

5.4 Concepts You Must Understand First

  1. container_t and sVirt labeling
  2. MCS categories and isolation
  3. Volume relabeling semantics

5.5 Questions to Guide Your Design

  1. How will you prove that categories enforce isolation?
  2. How will you demonstrate :Z vs :z clearly?
  3. How will you collect AVC denials for evidence?

5.6 Thinking Exercise

Draw a table with two containers and two volumes. Predict which access attempts should succeed.

5.7 The Interview Questions They’ll Ask

  1. “What does :Z do in a container volume mount?”
  2. “How do MCS categories enforce isolation?”
  3. “Why can root inside a container be denied access?”

5.8 Hints in Layers

Hint 1: Start with label inspection

Hint 2: Add a denial case without relabeling

Hint 3: Add shared volume case with :z

5.9 Books That Will Help

Topic Book Chapter
SELinux containers “SELinux System Administration” Container section
MAC systems “Operating Systems: Three Easy Pieces” Security chapters

5.10 Implementation Phases

Phase 1: Foundation (4-5 days)

Goals:

  • Build scripts to start containers and inspect labels.

Tasks:

  1. Use podman to start containers with a known image.
  2. Capture labels with ps -eZ and ls -Z.

Checkpoint: Labels collected and stored in a report.

Phase 2: Core Functionality (1 week)

Goals:

  • Demonstrate isolation and volume labeling.

Tasks:

  1. Add access tests between containers.
  2. Implement :Z and :z volume examples.

Checkpoint: Tests show expected allow/deny outcomes.

Phase 3: Polish & Edge Cases (4-5 days)

Goals:

  • Add AVC analysis and documentation.

Tasks:

  1. Collect AVC logs for failed access.
  2. Document fixes and interpretations.

Checkpoint: Lab guide includes evidence and remediation notes.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Runtime podman vs docker podman better SELinux integration
Volume mode :Z vs :z use both teaches trade-offs
Reporting text vs JSON text deterministic and simple

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Isolation Tests Cross-container access read neighbor volume
Volume Tests relabeling behavior :Z vs :z
Regression Tests stable outputs fixed image digest

6.2 Critical Test Cases

  1. Container A cannot read Container B’s private volume.
  2. Container A can read its own :Z volume.
  3. Shared :z volume is readable by both.

6.3 Test Data

/srv/selinux-lab/a
/srv/selinux-lab/b

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Forgetting :Z Access denied Relabel with :Z
Using :z for private data Cross-container access Use :Z
SELinux disabled No labels Enable SELinux and relabel

7.2 Debugging Strategies

  • Use ausearch -m avc after each failure.
  • Inspect labels on host and inside container.

7.3 Performance Traps

  • Excessive container creation can exhaust category pool; reuse containers.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add a script to display category mappings.
  • Add a host file access denial demo.

8.2 Intermediate Extensions

  • Demonstrate relabeling with :z vs :Z side-by-side.
  • Add a read-only volume scenario.

8.3 Advanced Extensions

  • Integrate with Kubernetes (SELinux labels in pods).
  • Add automatic category pool monitoring.

9. Real-World Connections

9.1 Industry Applications

  • Secure multi-tenant container hosting.
  • Hardening CI/CD runners.
  • Podman and CRI-O SELinux integration.
  • SELinux reference policy.

9.3 Interview Relevance

  • Container isolation and SELinux labeling.
  • MAC vs DAC in container environments.

10. Resources

10.1 Essential Reading

  • Red Hat container SELinux documentation
  • “SELinux by Example” (MCS chapters)

10.2 Video Resources

  • Container security conference talks

10.3 Tools & Documentation

  • podman, docker, ls -Z, ps -eZ

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain how container labels are assigned.
  • I understand how MCS categories enforce isolation.
  • I can diagnose volume labeling failures.

11.2 Implementation

  • Lab scripts are repeatable.
  • Isolation tests behave as expected.
  • AVC evidence is captured.

11.3 Growth

  • I can teach a teammate why :Z is required.
  • I documented the trade-offs of :z.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Demonstrate basic container labeling and denial.

Full Completion:

  • Show :Z vs :z and cross-container isolation.

Excellence (Going Above & Beyond):

  • Extend the lab to Kubernetes SELinux labels.

13 Additional Content Rules (Hard Requirements)

13.1 Determinism

  • Use fixed image digests and lab paths.

13.2 Outcome Completeness

  • Provide success and failure demos in the lab scripts.

13.3 Cross-Linking

  • Link to P10 for MLS/MCS and P01 for context inspection.

13.4 No Placeholder Text

  • All sections contain concrete steps.