Linux ACLs Explained: getfacl and setfacl Beyond rwx Permissions
Standard Linux permissions answer three questions: what can the owner do, what can the owning group do, what can everyone else do. That model covers most situations and then hits a wall on the first request like “can Sarah from accounting also read these files without joining our group.” Access control lists are the answer built into every major Linux filesystem, managed with two commands: getfacl and setfacl.
The problem ACLs solve
A directory of reports owned by analytics:analytics with mode 750 gives the analytics group full access and everyone else nothing. Now one specific user outside the group needs read access. Your options under the classic model are all bad: add her to the analytics group (she gets access to everything the group touches), create a new shared group just for this directory (group sprawl, and a file has only one group), or open the files to everyone (no).
An ACL expresses it directly:
setfacl -m u:sarah:rX /srv/reports -R
Sarah can now read the reports. Nobody else gained or lost anything.
Reading ACLs
ls -l hints at ACL presence with a + after the mode bits:
-rw-rw-r--+ 1 admin analytics 4096 Aug 18 report.csv
getfacl shows the actual list:
getfacl report.csv
# file: report.csv
# owner: admin
# group: analytics
user::rw-
user:sarah:r--
group::rw-
mask::rw-
other::r--
The bare user:: and group:: lines are the classic owner and owning-group permissions; user:sarah: is the named ACL entry; mask:: is new and important, covered below.
Setting entries with setfacl
# Named user: read and execute-if-directory
setfacl -m u:sarah:rX file-or-dir
# Named group: read/write for the web team
setfacl -m g:webteam:rw shared.conf
# Multiple entries at once
setfacl -m u:sarah:r,g:webteam:rw,u:deploy:rwx project/
# Recursive over an existing tree
setfacl -R -m g:webteam:rwX /srv/site
The capital X grants execute only on directories and on files already executable by someone, the same convention as chmod, and is what you almost always want in recursive operations so data files do not become executable.
Removing is symmetric: setfacl -x u:sarah file deletes her entry, and setfacl -b file wipes all extended entries, restoring pure classic permissions.
The mask: the part everyone trips over
Every file with named entries has a mask, the ceiling for all permissions except the owner’s and other’s. Effective permissions are the AND of the entry and the mask, and getfacl flags the difference:
user:sarah:rw- #effective:r--
mask::r--
Sarah’s entry says rw, the mask caps it at r. What makes this genuinely confusing is that chmod g-w on an ACL-bearing file modifies the mask, not the owning group entry. A well-meaning chmod can silently cap every named user’s access. When ACL permissions seem to not apply, check the mask first: setfacl -m m::rwx file raises it.
Default ACLs: inheritance for shared directories
Regular ACL entries apply to existing files. Default ACLs, set on directories with -d, are templates inherited by everything created inside afterward:
mkdir /srv/shared
setfacl -m g:teamalpha:rwX,g:teambeta:rwX /srv/shared
setfacl -d -m g:teamalpha:rwX,g:teambeta:rwX /srv/shared
The first command grants both teams access to the directory itself; the second ensures every file either team creates inside automatically carries both entries. This pair is the canonical recipe for a two-team shared directory, the use case that classic permissions simply cannot express, and it composes with the setgid bit on the directory for consistent group ownership.
Backups and copies
Not everything preserves ACLs. cp needs -p or --preserve=all; rsync needs -A on top of -a; GNU tar needs --acls on both create and extract. mv within a filesystem preserves them, since the inode is untouched. If ACLs matter in your backup strategy, verify with getfacl on a restored file, not by assumption. Modern filesystems (ext4, XFS, Btrfs) all support ACLs out of the box on current distributions, so the old advice about mount options is mostly historical.
When not to use ACLs
ACLs add invisible complexity: permissions no longer fit in the ls -l column your eyes are trained on, and debugging requires getfacl on suspicion. If a plain group solves the problem cleanly, use the group. Reach for ACLs when the requirement is genuinely “these two-plus parties need different access to the same tree,” and document where you have used them so the next administrator knows the + signs are load-bearing.
Frequently Asked Questions
What are ACLs in Linux?
Access control lists extend the standard owner, group, and other permission model by letting you attach additional named users and groups to a file, each with their own read, write, and execute bits.
When do I need ACLs instead of chmod?
When more than one group or specific user needs distinct access to the same files and the single owner-group-other model cannot express it, for example giving one extra user read access to a directory owned by another team.
How can I tell if a file has an ACL?
ls -l shows a plus sign after the permission bits, such as -rw-rw-r—+. Run getfacl on the file to see the full list.
What is the ACL mask?
The mask is an upper limit applied to all named users, named groups, and the owning group. If the mask is r—, no ACL entry can grant more than read, whatever it says. chmod on the group bits actually modifies the mask on files with ACLs.
What is a default ACL?
A default ACL on a directory is inherited by files and subdirectories created inside it. It is how you make a shared directory where everything created automatically carries the right ACL entries.
How do I remove ACLs from a file?
setfacl -x removes a specific entry, and setfacl -b strips all extended ACL entries, returning the file to plain owner, group, and other permissions.