DevOps

File Permissions

Understanding Permissions

Every file and directory in Linux has three sets of permissions assigned to three categories of users:

-rwxr-xr--  1  alice  developers  4096  May 15 10:30  script.sh
│└─┬──┘└┬─┘└┬─┘ └─┬─┘ └───┬────┘ └──┬─┘               └──┬───┘
│  │   │   │    │        │        │                    │
│  │   │   │    │        │        └── size            └── name
│  │   │   │    │        └─ group
│  │   │   │    └── owner
│  │   │   └── other permissions (r--)
│  │   └── group permissions (r-x)
│  └── owner permissions (rwx)
└── file type (- = file, d = directory, l = symlink)

Permission Bits

SymbolNameOn fileOn directory
rreadread filelist contents (ls)
wwritemodify filecreate/delete items
xexecuterun as programenter directory (cd)
-nonepermission deniedpermission denied

File Types

SymbolType
-regular file
ddirectory
lsymbolic link
ccharacter device
bblock device
pnamed pipe
ssocket

Octal Notation

Permissions can be represented as octal (base-8) numbers. Each permission triplet maps to a 3-bit value:

BinaryOctalPermissions
0000---
0011--x
0102-w-
0113-wx
1004r--
1015r-x
1106rw-
1117rwx

Common permission patterns:

OctalSymbolicUse case
644rw-r--r--Regular files
600rw-------Private files (SSH keys)
755rwxr-xr-xExecutables, directories
700rwx------Private executables
777rwxrwxrwxWorld-writable (avoid!)
664rw-rw-r--Group-writable files
775rwxrwxr-xGroup-executable directories

Quick memory trick: Owner=4+2+1=7, Group=4+0+1=5, Other=4+0+0=4 → 754


chmod and chown Commands

chmod — Change Mode

# Octal notation
chmod 755 script.sh         # rwxr-xr-x
chmod 644 config.txt        # rw-r--r--
chmod 600 ~/.ssh/id_rsa     # rw------- (private key)
chmod -R 755 /var/www/      # recursive

# Symbolic notation: [who][+/-/=][permissions]
chmod u+x script.sh         # add execute for owner
chmod g+w file.txt          # add write for group
chmod o-r secret.txt        # remove read from others
chmod a+r public.txt        # add read for all
chmod u=rwx,g=rx,o= dir/    # set explicitly
chmod +x script.sh          # add execute for all (shorthand)

chown — Change Owner

chown alice file.txt            # change owner
chown alice:devs file.txt       # change owner and group
chown :devs file.txt            # change group only
chown -R www-data /var/www/     # recursive
chown --reference=ref.txt file  # copy ownership from ref

chgrp — Change Group

chgrp devs file.txt         # change group
chgrp -R devs /project/     # recursive

Special Permissions

# SUID (Set User ID) — run as file owner
chmod u+s /usr/bin/passwd   # octal: 4755
# SGID (Set Group ID) — run as group / inherit group on dirs
chmod g+s /shared/          # octal: 2755
# Sticky bit — only owner can delete in directory
chmod +t /tmp               # octal: 1777

# Combined with octal (4=SUID, 2=SGID, 1=sticky)
chmod 4755 program          # SUID + rwxr-xr-x
chmod 2775 shared-dir       # SGID + rwxrwxr-x
chmod 1777 /tmp             # sticky + rwxrwxrwx

umask — Default Permissions

umask           # show current umask (e.g., 0022)
umask 0027      # set umask for session
# umask subtracts from 666 (files) and 777 (dirs)
# umask 022 → files: 644, dirs: 755
# umask 027 → files: 640, dirs: 750

Access Control Lists (ACL)

Standard Unix permissions only allow one owner and one group. ACLs extend this by letting you set permissions for any user or group.

Checking ACL Support

# Verify filesystem is mounted with ACL support
mount | grep acl
# or check /etc/fstab for "acl" option

getfacl — View ACL

getfacl file.txt
# Output:
# file: file.txt
# owner: alice
# group: devs
# user::rw-
# group::r--
# other::r--

setfacl — Set ACL

# Grant bob read+write on file.txt
setfacl -m u:bob:rw file.txt

# Grant devs group execute on script.sh
setfacl -m g:devs:rx script.sh

# Remove ACL entry for bob
setfacl -x u:bob file.txt

# Remove all ACLs
setfacl -b file.txt

# Recursive (apply to directory and contents)
setfacl -R -m u:bob:rw /project/

# Set default ACL (inherited by new files in directory)
setfacl -d -m u:bob:rw /shared/

# Copy ACL from one file to another
getfacl source.txt | setfacl --set-file=- dest.txt

Practical ACL Example

# Scenario: web team needs read access to /var/app/config
# but standard group permissions would expose too much

setfacl -m g:webteam:r /var/app/config
setfacl -m u:deploy:rw /var/app/config

# Verify
getfacl /var/app/config
# user::rw-
# user:deploy:rw-
# group::---
# group:webteam:r--
# mask::rw-
# other::---

Note: When using ACLs, ls -l shows a + at the end of the permissions string (e.g., rw-r--r--+) to indicate that extended ACLs are set.