Standard Linux permissions allow one owner, one group and everyone else. Sometimes that is not enough: a deploy user needs write access to a folder owned by the web server, and a backup user needs read access to everything. Access control lists (ACLs) add extra entries for named users and groups. This guide shows how to read, set, inherit and remove ACLs.
Before you start
- A Linux VPS with Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9.
- Root or sudo access over SSH.
- Comfort with normal permissions. If needed, read Linux file permissions explained first.
Install the tools and check filesystem support
The setfacl and getfacl commands come from the acl package. AlmaLinux and Rocky install it by default. On Ubuntu and Debian, install it if it is missing:
sudo apt update && sudo apt install aclOn AlmaLinux or Rocky:
sudo dnf install aclext4 and XFS, the usual filesystems on these systems, support ACLs out of the box, with no extra mount option. Check the filesystem type of a path with:
df -T /var/wwwRead ACLs with getfacl
getfacl --omit-header /var/www/example.comWithout --omit-header, the output also starts with three comment lines naming the file, owner and group.
user::rwx
group::r-x
other::r-xWith no ACL set, the output just mirrors the normal permissions. A + at the end of the mode in ls -l, such as drwxr-xr-x+, tells you a file has extra ACL entries.
Grant access to a user or group
Give the user deploy read and write access to one file:
sudo setfacl -m u:deploy:rw /var/www/example.com/config.phpGive the group developers full access to a folder:
sudo setfacl -m g:developers:rwx /var/www/example.com-mmodifies (adds or changes) entries.u:name:permstargets a user andg:name:permsa group.- Permissions use the familiar
r,wandxletters.
Apply to a whole tree with -R. Use capital X so only folders get execute:
sudo setfacl -R -m u:deploy:rwX /var/www/example.comSet default ACLs for new files
An ACL on a folder does not apply to files created later. For that you need a default ACL, which new files and folders inherit:
sudo setfacl -R -m d:u:deploy:rwX /var/www/example.comThe d: prefix marks a default entry. Usually you set both: a normal entry for what exists now and a default entry for what comes later:
sudo setfacl -R -m u:deploy:rwX,d:u:deploy:rwX /var/www/example.comNow any file the web server creates in this tree is also writable by deploy.
Understand the mask
When ACL entries exist, the group bits shown by ls -l become the mask. The mask caps what named users and groups can actually do. getfacl shows it, and marks entries the mask reduces with #effective::
user:deploy:rwx #effective:r-x
mask::r-xHere deploy has rwx on paper but only r-x in practice. A chmod g-w on the file lowers the mask and silently removes write access from every ACL entry. Reset it with:
sudo setfacl -m m::rwx /var/www/example.comRemove ACLs
Remove one entry:
sudo setfacl -x u:deploy /var/www/example.com/config.phpRemove default entries from a folder:
sudo setfacl -k /var/www/example.comRemove every ACL entry and go back to plain permissions:
sudo setfacl -R -b /var/www/example.comBack up and restore ACLs
getfacl output can be saved and replayed, which helps before large changes:
getfacl -R /var/www/example.com > /root/example-acl.txt
sudo setfacl --restore=/root/example-acl.txtRun the restore from /, because getfacl stores relative paths. Note that cp and many backup tools do not copy ACLs unless asked: use cp -a, rsync -A or tar --acls.
When ACLs beat groups
Use groups first. They are simpler and visible in ls -l. Reach for ACLs when:
- One extra user needs access, but you cannot change the owner or group, for example a folder owned by
www-data. - Different users need different rights on the same folder.
- New files must stay accessible no matter which program creates them.
Check it works
Confirm the entry and its effective rights with getfacl, then test as the user:
getfacl /var/www/example.com | grep deploy
sudo -u deploy touch /var/www/example.com/acl-test && echo OK
sudo rm /var/www/example.com/acl-testOK means deploy can write in the folder.
Troubleshooting
- "setfacl: command not found": install the
aclpackage as shown above. - "Operation not supported": the filesystem or mount does not support ACLs. Check it with
df -Tandfindmnt. - ACL is set but access is denied: the mask is too strict, or a parent folder lacks
xfor the user. Check#effective:in getfacl, and walk the path withnamei -l. - New files lack the ACL: you set only access entries. Add default entries with
d:.
Next steps
- Compare with the simpler group approach: Create a shared folder several users can edit.
- Track down remaining errors: Fix "Permission denied" on Linux.
