Linux file permissions and Access Control Lists (ACLs) allow you to define exactly who can read, write, and execute files and directories.

Let’s see this in action. Imagine you have a directory /srv/shared_data that a group of users, devs, needs to collaborate on.

# Create the directory
sudo mkdir /srv/shared_data

# Create a group for developers
sudo groupadd devs

# Add some users to the group (replace with actual usernames)
sudo usermod -aG devs alice
sudo usermod -aG devs bob

# Set basic ownership and permissions
sudo chown root:devs /srv/shared_data
sudo chmod 770 /srv/shared_data

With chmod 770, the owner (root) and members of the devs group can read, write, and enter (rwx) the directory, while others have no access (---). This is the traditional Unix permission model.

But what if alice needs to give charlie (who isn’t in the devs group) read-only access to a specific file inside /srv/shared_data, say /srv/shared_data/project_docs/report.txt, without giving charlie write access or affecting anyone else? This is where ACLs shine.

First, ensure your filesystem supports ACLs and they are mounted with the acl option (most modern Linux distributions do this by default). You can check with mount | grep " / ". If it’s not there, you’d need to remount or edit /etc/fstab.

Now, let’s set the ACL for report.txt.

# Create a sample file (assuming report.txt doesn't exist yet)
sudo touch /srv/shared_data/project_docs/report.txt
sudo chown root:devs /srv/shared_data/project_docs/report.txt
sudo chmod 660 /srv/shared_data/project_docs/report.txt

# Grant read-only access to charlie
sudo setfacl -m u:charlie:r-- /srv/shared_data/project_docs/report.txt

You can verify the ACLs with getfacl:

getfacl /srv/shared_data/project_docs/report.txt

The output will look something like this:

# file: srv/shared_data/project_docs/report.txt
# owner: root
# group: devs
user::rw-
group::rw-
other::---
# extended attributes:
user:charlie:r--

Notice the user:charlie:r-- line. This grants charlie read permission specifically, overriding the default "other" permissions. The + sign at the end of the permissions in ls -l output also indicates an ACL is present.

The core problem ACLs solve is the limitation of the traditional owner/group/other permission model. It’s too coarse-grained for complex collaboration scenarios. ACLs provide a way to define permissions for specific users or groups beyond the primary owner and group. This allows for much finer-grained control, enabling scenarios like granting a temporary contractor read access to a sensitive directory without making them a formal group member or giving them broader access than intended.

When you set an ACL, the system checks it before falling back to the standard Unix permissions. So, if charlie is also in the devs group (which has rw-), the user:charlie:r-- entry takes precedence, granting charlie only read access. If charlie were not in the devs group and had no other specific entry, they would fall under the other::--- rule and have no access.

A common pitfall is forgetting to set default ACLs on directories. If you set an ACL on a file, it only applies to that file. To ensure new files and subdirectories created within /srv/shared_data/project_docs automatically inherit permissions, you’d use setfacl -d. For instance, to make sure new files inherit read/write for the devs group and read-only for charlie:

sudo setfacl -d -m g:devs:rw- /srv/shared_data/project_docs
sudo setfacl -d -m u:charlie:r-- /srv/shared_data/project_docs

Now, any file created in project_docs will automatically have these default ACLs applied.

The next concept you’ll likely encounter is managing ACLs for directories, specifically how rwx permissions on a directory interact with ACLs to control entry, file creation, and subdirectory creation.

Want structured learning?

Take the full Linux & Systems Programming course →