Course contentsShow
← Linux
Lesson 979 of 1,8199. Security Hardening and Mandatory Access ControlFree lesson

Profiles for Multi-User Environments

Develop profiles that allow for shared application usage while maintaining strict user data isolation.

In this lesson, you will learn how to design AppArmor profiles that permit multiple users to execute the same shared application while ensuring their personal data remains strictly isolated.

Balancing Shared Execution with Private Data

In a multi-user environment, you often have a single binary—such as a data processing script or a customized text editor—installed in a global location like /usr/local/bin/. While the executable is shared, the data it touches must be private to each user. If you simply write a broad rule allowing access to /home/*, you create a security hole where any user could potentially read another’s sensitive files through the application.

To solve this, we leverage AppArmor variables combined with path-based restrictions. Instead of hardcoding paths, we define a variable (e.g., @{HOME}) to dynamically scope access to the user currently running the process.

Implementing User Isolation

When building the profile, we grant read/write access to the specific locations where the application needs to store state, but we restrict it to the current user's home directory.

Consider a shared tool that processes logs in a ~/work/ directory:

profile shared-processor /usr/local/bin/processor {
  # Allow execution of shared libraries and binaries
  /usr/local/bin/processor mr,
  /usr/lib/** mr,

  # Use the @{HOME} variable to enforce isolation
  owner @{HOME}/work/ rw,
  owner @{HOME}/work/** rw,

  # Deny access to other users' directories
  deny /home/*/** w,
}

Why this works

  1. The owner keyword: This is the most critical component. It tells the kernel to verify that the file being accessed is owned by the user ID (UID) of the process currently running the profile. Even if the application attempts to open /home/bob/work/data.txt while running as alice, the kernel will block the access because the UIDs do not match.
  2. Explicit Deny: By adding a deny rule for the broader /home/* tree, we create a "fail-safe" layer that prevents the application from accidentally escaping its intended user-scope if the profile logic is modified improperly.

Key Takeaway: Use the owner keyword in conjunction with AppArmor variables like @{HOME} to enforce a strict boundary that prevents shared applications from accessing data outside the current user's filesystem scope.