Access Control Lists and Permission Troubleshooting
Owner/group/other modes intentionally provide a compact policy. Real systems sometimes need named-user or named-group access without changing the owning group. POSIX ACLs add those entries and an ACL mask. They also add a common troubleshooting trap: displayed mode bits can summarize the ACL mask rather than a single group entry. This lesson combines ACL mechanics with a disciplined permission-debugging workflow.
Learning objectives
By the end of this lesson
- Recognize minimal and extended ACLs in
lsandgetfacloutput. - Create, modify, remove, and copy access ACL entries.
- Explain how the ACL mask limits named users, named groups, and the owning group.
- Use default directory ACLs to establish inherited access.
- Troubleshoot permission failures across identity, path traversal, modes, ACLs, mount state, and later security layers.
1. ACLs extend the group-class decision
An extended access ACL can contain named-user and named-group entries in addition to the file owner, owning group, and other entries. The ACL mask limits the effective permissions of named users, named groups, and the owning-group entry. The file owner entry and other entry are not limited by that mask.
flowchart TB
P["Process effective UID and groups"] --> O{"Matches file owner?"}
O -->|yes| UE["Use owner entry"]
O -->|no| NU{"Named user entry?"}
NU -->|yes| UM["Named-user entry AND mask"]
NU -->|no| GM{"Any matching group entries?"}
GM -->|yes| AG["Union matching groups AND mask"]
GM -->|no| OT["Use other entry"]
UE --> R{"Requested access allowed?"}
UM --> R
AG --> R
OT --> Rlab="$HOME/devops-academy/linux/chapter06/lesson05"
mkdir -p -- "$lab"
printf 'deployment=approved
' > "$lab/release.txt"
ls -l -- "$lab/release.txt"
getfacl -p -- "$lab/release.txt"A plus sign after the mode string in many ls -l implementations indicates additional ACL information. Use getfacl for the authoritative entry set and effective-permission comments.
2. setfacl changes named entries and the mask
The common modify form is setfacl -m SPEC FILE. Entries include u:NAME:PERMS, g:NAME:PERMS, and m::PERMS for the mask. -x removes selected entries and -b removes all extended entries.
file="$HOME/devops-academy/linux/chapter06/lesson05/release.txt"
# Add a named-user entry for an account commonly present on Linux systems.
if getent passwd nobody >/dev/null; then
setfacl -m u:nobody:r-- -- "$file"
fi
# Add a named group entry only when a supplementary group is available.
primary_group=$(id -gn)
acl_group=$(id -nG | tr ' ' '\n' | awk -v primary="$primary_group" '$0 != primary { print; exit }')
if [ -n "$acl_group" ]; then
setfacl -m "g:$acl_group:r--" -- "$file"
fi
# Inspect entries and effective permissions.
getfacl -p -- "$file"
# Remove the named nobody entry if it was added.
if getent passwd nobody >/dev/null; then
setfacl -x u:nobody -- "$file"
fiBy default, setfacl may recalculate the mask to include permissions required by modified entries. Use explicit mask management only when the policy is understood; an unexpectedly narrow mask is a frequent source of “the ACL says rw but access is read-only” incidents.
3. The mask defines effective group-class access
Consider a named entry user:deploy:rw- with mask r--. The stored entry requests read/write, but its effective permission is read-only because write is removed by the mask. getfacl normally prints an #effective: annotation when the mask reduces an entry.
file="$HOME/devops-academy/linux/chapter06/lesson05/mask-demo.txt"
printf 'mask demo
' > "$file"
if getent passwd nobody >/dev/null; then
setfacl -m u:nobody:rw- -- "$file"
setfacl -m m::r-- -- "$file"
getfacl -p -- "$file"
# Restore a mask that allows the named write permission.
setfacl -m m::rw- -- "$file"
fiOn a file with an extended ACL, changing the traditional group mode bits generally changes the ACL mask. A later chmod g-w can therefore reduce effective permissions for several named entries, not only the owning group.
4. Default ACLs define inherited entries for new children
A directory can carry a default ACL. When a child is created, that default is used to derive the child’s access ACL, constrained by the creating program’s requested mode. Default ACLs are not retroactive and do not automatically repair existing content.
shared="$HOME/devops-academy/linux/chapter06/lesson05/shared"
rm -rf -- "$shared"
mkdir -p -- "$shared"
chmod 2770 -- "$shared"
# Give the owning group inherited read/write on files and traversal on dirs.
setfacl -m d:u::rwx,d:g::rwx,d:o::---,d:m::rwx -- "$shared"
printf 'new artifact
' > "$shared/artifact.txt"
mkdir -- "$shared/release-dir"
getfacl -p -- "$shared"
getfacl -p -- "$shared/artifact.txt"
getfacl -p -- "$shared/release-dir"For a named team group, add both an access entry on the directory and a default named-group entry, then ensure the default mask permits the intended rights. Always create a test child and inspect it.
5. Troubleshoot permissions from the process outward
Reading, opening for write, creating, renaming, deleting, and executing require different checks.
Record effective UID, groups, service configuration, container user, and credential transitions.
Use namei -l; inspect parent-directory execute and write semantics.
Use stat and getfacl; read effective mask annotations.
Read-only mounts, unsupported ACLs, NFS identity, immutable attributes, quotas, or full filesystems can resemble permission failures.
SELinux, AppArmor, systemd sandboxing, container confinement, and capabilities are covered later; ordinary mode repair will not override them.
target="$HOME/devops-academy/linux/chapter06/lesson05/shared/artifact.txt"
id
namei -l -- "$target"
stat -c 'mode=%A octal=%a owner=%U:%G ids=%u:%g type=%F name=%n' -- "$target"
getfacl -p -- "$target"
findmnt -T "$target" -o TARGET,SOURCE,FSTYPE,OPTIONS
lsattr -- "$target" 2>/dev/null || true
df -h -- "$target"
df -i -- "$target"Capture identity, metadata, ACLs, mount options, and the failing command. A broad repair may restore service while destroying the evidence needed to understand why it failed.
6. Hands-on lab: create and diagnose an ACL policy
The getfacl and setfacl tools are commonly provided by an acl package. The lab exits with a clear message if they are unavailable.
set -eu
command -v getfacl >/dev/null || { printf 'Install the acl tools first.
' >&2; exit 1; }
command -v setfacl >/dev/null || { printf 'Install the acl tools first.
' >&2; exit 1; }
lab="$HOME/devops-academy/linux/chapter06/lesson05"
root="$lab/acl-lab"
rm -rf -- "$root"
mkdir -p -- "$root/shared"
printf 'build=42
' > "$root/shared/manifest.txt"
chmod 750 -- "$root/shared"
chmod 640 -- "$root/shared/manifest.txt"
# Add and then deliberately mask a named entry when nobody exists.
if getent passwd nobody >/dev/null; then
setfacl -m u:nobody:rw-,m::r-- -- "$root/shared/manifest.txt"
fi
{
printf '=== identity ===
'
id
printf '
=== path ===
'
namei -l -- "$root/shared/manifest.txt"
printf '
=== stat ===
'
stat -c '%A %a %U:%G %n' -- "$root/shared/manifest.txt"
printf '
=== acl before repair ===
'
getfacl -p -- "$root/shared/manifest.txt"
} > "$lab/acl-diagnosis.txt"
# Repair the ACL mask if the named entry exists.
if getent passwd nobody >/dev/null; then
setfacl -m m::rw- -- "$root/shared/manifest.txt"
fi
printf '
=== acl after repair ===
' >> "$lab/acl-diagnosis.txt"
getfacl -p -- "$root/shared/manifest.txt" >> "$lab/acl-diagnosis.txt"
cat -- "$lab/acl-diagnosis.txt"Verification checklist
7. Common ACL and troubleshooting mistakes
Reading only ls -l
Extended ACL entries and effective mask reductions require getfacl.
Ignoring parent traversal
A correct file ACL cannot compensate for a blocked parent directory.
Running chmod after ACL design without review
Group-mode changes can modify the ACL mask and reduce several entries.
Changing permissions before reproducing identity
The incident may belong to a service user, container UID, or sandbox rather than your interactive shell.
8. Knowledge check
Question 1. Which ACL entries are limited by the ACL mask?
Question 2. Why can an ACL entry display rw- but have only read access effectively?
getfacl shows this with an effective-permission annotation.Question 3. What should be inspected before changing a file that reports permission denied?
9. Summary
POSIX ACLs add named identities and default inheritance to the traditional permission model, while the ACL mask defines effective group-class access. Permission troubleshooting must proceed from the real process identity through path traversal, modes, ownership, ACLs, filesystem state, and additional security controls. Preserve evidence, make the smallest repair, and verify the exact operation.
10. Further reading
- Linux man-pages and ACL manuals:
acl(5),getfacl(1), andsetfacl(1). - POSIX access-control list model and Linux filesystem ACL documentation.
- Linux man-pages:
path_resolution(7),stat(2), andmount(8). - Filesystem manuals for extended attributes, mount options, and ACL support.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.