Every file and directory has three permission sets: owner, group, and others. Each set can allow
read (r), write (w), and execute (x). chmod
changes these bits using symbolic or octal notation.
Symbolic mode
# Add execute for owner
chmod u+x script.sh
# Remove write for others
chmod o-w file.txt
# Set read/write for owner, read for group, none for others
chmod u=rw,g=r,o= file.txt
Octal mode
Each digit is owner / group / others, where:
4 = read
2 = write
1 = execute
Common octal examples
# rwxr-xr-x
chmod 755 script.sh
# rw-r--r--
chmod 644 file.txt
# rwxr-x---
chmod 750 private_dir
Directories need the execute bit (x) to allow entering and listing contents.
Ownership controls which user and group the permission bits apply to. chown changes
the owner and group; chgrp changes only the group.
Change owner and group
# Set owner to www-data, group to www-data
sudo chown www-data:www-data /var/www/site
# Recursively change ownership
sudo chown -R www-data:www-data /var/www/site
Change only group
sudo chgrp developers /srv/shared
Use recursive changes carefully. On web roots, it’s common to set ownership once and then manage
permissions with chmod and ACLs.
Special permission bits modify how executables and directories behave: setuid, setgid, and the
sticky bit. They are powerful and must be used deliberately.
setuid (4xxx)
Executable runs with the file owner’s privileges.
# Example: /usr/bin/passwd
ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root ... /usr/bin/passwd
The s in the owner execute position indicates setuid.
setgid (2xxx)
On executables: run with file group’s privileges. On directories: new files inherit the directory’s group.
# Set setgid on a shared directory
sudo chmod 2770 /srv/shared
sudo chgrp developers /srv/shared
New files in /srv/shared will have group developers.
Sticky bit (1xxx)
On directories, only the owner of a file (or root) can delete it, even if others have write access.
# Typical on /tmp
ls -ld /tmp
drwxrwxrwt ...
# t in others execute position = sticky bit
Avoid setting setuid/setgid on custom binaries unless you fully understand the security impact.
POSIX ACLs allow per‑user and per‑group permissions beyond the single owner/group/other model.
They’re ideal for shared directories where multiple groups need different access levels.
View ACLs
getfacl /srv/shared
Add user ACL
# Give user alice read/write on directory
sudo setfacl -m u:alice:rwX /srv/shared
Add group ACL
# Give group qa read-only
sudo setfacl -m g:qa:r-X /srv/shared
Default ACLs for new files
# Ensure new files inherit ACLs
sudo setfacl -d -m u:alice:rwX /srv/shared
sudo setfacl -d -m g:qa:r-X /srv/shared
Default ACLs (-d) apply to newly created files and directories inside the target
directory, preserving your intended access model over time.
Web root for a single app
# Ownership: web server user
sudo chown -R www-data:www-data /var/www/site
# Permissions: owner rwx, group r-x, others ---
sudo chmod -R 750 /var/www/site
This pattern lets the web server read and execute files while blocking world access. Developers
can be added to the www-data group if they need direct access.
Shared project directory for a team
# Create group and directory
sudo groupadd project
sudo mkdir -p /srv/project
# Set group ownership and setgid
sudo chown root:project /srv/project
sudo chmod 2770 /srv/project
All files created in /srv/project inherit group project. Only group
members can read/write; others have no access.
Logs readable by a support group
# Logs owned by root:adm (typical)
ls -ld /var/log
# Add ACL for support group
sudo setfacl -m g:support:r-X /var/log/app
ACLs are ideal when you need to grant read access to logs without changing primary ownership or
weakening global permissions.