Linux permissions cheat sheet

Quick Reference

Permission Model
Owner · Group · Others
Basic Bits
r (4) · w (2) · x (1)
Special Bits
SUID · SGID · Sticky
Change Permissions
chmod
Change Owner
chown
Change Group
chgrp

The Permission String

Every file and directory has a 10-character permission string visible in ls -l output. Understanding how to read it is the foundation of Linux permissions.

Example: -rwxr-xr--

rwx rx r
File type (- = file, d = directory, l = symlink)
Owner permissions: rwx = read + write + execute
Group permissions: r-x = read + execute, no write
Others permissions: r– = read only
CharacterPositionMeaning
-1Regular file
d1Directory
l1Symbolic link
c1Character device (e.g. /dev/tty)
b1Block device (e.g. /dev/sda)
r2, 5, 8Read permission
w3, 6, 9Write permission
x4, 7, 10Execute permission
-anyPermission not set
s4 or 7SUID (pos 4) or SGID (pos 7) with execute
S4 or 7SUID or SGID set but execute bit is NOT set
t10Sticky bit set, execute bit set
T10Sticky bit set, execute bit NOT set

Permission Bits & Octal Notation

Each permission triplet (owner, group, others) is represented as a 3-bit binary number, written as a single octal digit. This is the basis of numeric chmod.

BinaryOctalSymbolicPermissions
0000---None
0011--xExecute only
0102-w-Write only
0113-wxWrite + execute
1004r--Read only
1015r-xRead + execute
1106rw-Read + write
1117rwxRead + write + execute (full)

Common Octal Combinations

OctalSymbolicTypical Use
400r--------Read-only by owner only (e.g. private key backup)
600rw-------Read/write by owner only — SSH private keys
640rw-r-----Owner read/write, group read — config files
644rw-r--r--Owner read/write, everyone read — web files, configs
664rw-rw-r--Owner and group read/write — shared project files
700rwx------Full access for owner only — private scripts
750rwxr-x---Owner full, group execute — team scripts
755rwxr-xr-xOwner full, everyone read/execute — directories, public scripts, binaries
775rwxrwxr-xOwner and group full — shared directories
777rwxrwxrwxFull access for everyone — avoid in production
Never use 777 in production. Setting chmod 777 on files or directories grants any user on the system full read, write, and execute access. On web servers this is especially dangerous — any PHP/Python process can overwrite your files. Use 755 for directories and 644 for files as a baseline.

chmod — Change Permissions

Numeric (Octal) Mode

CommandWhat It Does
chmod 644 file.txtOwner rw, group r, others r
chmod 755 script.shOwner rwx, group rx, others rx
chmod 600 ~/.ssh/id_rsaSSH private key — owner rw only
chmod 700 ~/.sshSSH directory — owner only
chmod 000 file.txtNo permissions for anyone (even owner needs sudo to read)
chmod -R 755 /var/www/htmlApply recursively to directory and all contents

Symbolic Mode

Symbolic mode uses letters to add (+), remove (-), or set (=) permissions without specifying all bits at once.

WhoOperatorPermissionMeaning
uUser (owner)
gGroup
oOthers
aAll (u + g + o)
+Add permission
-Remove permission
=Set exactly (replaces existing)
CommandWhat It Does
chmod +x script.shAdd execute for owner, group, and others
chmod u+x script.shAdd execute for owner only
chmod g+w file.txtAdd write permission for group
chmod o-r file.txtRemove read permission from others
chmod a-x file.txtRemove execute from everyone
chmod u=rwx,g=rx,o=r file.txtSet exact permissions for each class
chmod g=u file.txtCopy owner permissions to group
chmod u-s fileRemove SUID bit from file
chmod -R a+rX /srv/sharedRecursively add read; add execute only to directories (X)
Capital X vs lowercase x: chmod +x adds execute to all files including regular files. chmod +X (capital X) adds execute only to directories and files that already have execute set for someone. Use chmod -R a+rX when making a directory tree readable — it avoids making regular files executable.

chown & chgrp — Change Ownership

CommandWhat It Does
chown alice file.txtChange owner to alice
chown alice:developers file.txtChange owner to alice AND group to developers
chown :developers file.txtChange group only (owner unchanged)
chown -R www-data:www-data /var/www/htmlRecursively change owner and group
chown --reference=ref.txt target.txtCopy ownership from another file
chgrp developers file.txtChange group to developers
chgrp -R developers /srv/projectRecursively change group
ls -l file.txtShow owner and group
stat file.txtShow full file metadata including ownership and octal permissions
Viewing numeric UID/GID: ls -ln shows numeric user and group IDs instead of names. Useful when UIDs don’t resolve to names (e.g. on NFS mounts or in containers).

Special Permission Bits

Three additional bits — SUID, SGID, and Sticky — control advanced privilege and sharing behaviour. They are set as a 4th octal digit (leading digit).

BitOctalOn FileOn DirectoryVisible As
SUID 4xxx File runs with the owner’s privileges, not the caller’s Ignored (on most Linux) s or S in owner execute position
SGID 2xxx File runs with the group’s privileges New files inherit the directory’s group (not creator’s) s or S in group execute position
Sticky 1xxx Ignored on modern Linux Only the file owner (or root) can delete/rename files inside t or T in others execute position

Examples in the Wild

PathPermissionsBitWhy It’s Set
/usr/bin/passwd-rwsr-xr-xSUIDRuns as root so any user can change their own password (writes to /etc/shadow)
/usr/bin/sudo-rwsr-xr-xSUIDMust run as root to grant elevated privileges
/usr/bin/ping-rwsr-xr-xSUIDRequires raw socket access (root on older systems)
/tmpdrwxrwxrwtStickyAnyone can create files; only owner can delete their own files
/var/maildrwxrwsr-xSGIDNew mail files inherit group mail regardless of creator

Setting Special Bits

CommandWhat It Does
chmod u+s /usr/local/bin/mytoolSet SUID on file
chmod 4755 /usr/local/bin/mytoolSet SUID + 755 permissions (numeric)
chmod g+s /srv/sharedSet SGID on directory
chmod 2775 /srv/sharedSet SGID + 775 (numeric)
chmod +t /tmp/mydirSet sticky bit on directory
chmod 1777 /tmp/mydirSet sticky + 777 (numeric)
chmod u-s fileRemove SUID
chmod g-s dirRemove SGID
SUID security risk: SUID binaries run with the file owner’s privileges. A SUID root binary with a vulnerability can be exploited to gain root. Regularly audit SUID files: find / -perm -4000 -type f 2>/dev/null. Any unexpected SUID binary is a red flag.

umask — Default Permission Mask

umask defines which permission bits are removed when new files and directories are created. It is subtracted from the maximum default (666 for files, 777 for directories).

umaskNew File ResultNew Directory ResultTypical Use
022644 (rw-r–r–)755 (rwxr-xr-x)Default on most Linux systems
027640 (rw-r—–)750 (rwxr-x—)Servers — group readable, no access for others
077600 (rw——-)700 (rwx——)High-security — owner only
002664 (rw-rw-r–)775 (rwxrwxr-x)Shared development environments
CommandWhat It Does
umaskShow current umask value
umask 027Set umask for current session
umask -SShow umask in symbolic format (u=rwx,g=rx,o=)
umask is not subtraction — it is a bitmask. For files: new permissions = 666 AND (NOT umask). For directories: 777 AND (NOT umask). umask 022 means “mask out write for group and others.” The result is 644 for files and 755 for directories. To make the change permanent, add umask 027 to ~/.bashrc, ~/.profile, or /etc/profile.

Finding Files by Permission

CommandWhat It Finds
find / -perm -4000 -type f 2>/dev/nullAll SUID files (security audit)
find / -perm -2000 -type f 2>/dev/nullAll SGID files
find / -perm -1000 -type d 2>/dev/nullAll directories with sticky bit
find /var/www -perm -o+w -type fWorld-writable files under /var/www (security risk)
find /etc -perm 777 2>/dev/nullFiles with full 777 permissions in /etc
find / -nouser 2>/dev/nullFiles with no valid owner (orphaned files)
find / -nogroup 2>/dev/nullFiles with no valid group
find /home -perm /o+rwx -not -type l 2>/dev/nullFiles in /home accessible by others
find . -perm -u+x -type fExecutable files in current directory tree
find /etc -maxdepth 1 -perm -o+r -type fConfig files in /etc readable by others

ACL — Access Control Lists

Standard Unix permissions allow only one owner and one group. ACLs extend this to grant access to arbitrary users and groups without changing ownership.

CommandWhat It Does
getfacl file.txtShow ACL for a file
setfacl -m u:alice:rw file.txtGive alice read+write access
setfacl -m g:developers:rx /srv/appGive developers group read+execute on directory
setfacl -m o::- file.txtRemove all permissions for others via ACL
setfacl -x u:alice file.txtRemove ACL entry for alice
setfacl -b file.txtRemove all ACL entries (revert to standard permissions)
setfacl -R -m g:developers:rx /srv/appApply ACL recursively
setfacl -d -m g:developers:rx /srv/appSet default ACL — new files inherit this ACL
getfacl source.txt | setfacl --set-file=- target.txtCopy ACL from one file to another
ACL indicator: When a file has an ACL, ls -l shows a + at the end of the permission string, e.g. -rw-r--r--+. The filesystem must be mounted with acl option (ext4 and XFS support it by default on most distributions). Install tools with apt install acl or yum install acl.

Common Permission Recipes

Web Server (Nginx / Apache)

CommandPurpose
chown -R www-data:www-data /var/www/htmlSet web server user as owner
find /var/www/html -type d -exec chmod 755 {} \;Directories: owner full, others read+execute
find /var/www/html -type f -exec chmod 644 {} \;Files: owner read/write, others read only
chmod 750 /var/www/html/adminAdmin directory: no access for others

SSH Keys

CommandPurpose
chmod 700 ~/.sshSSH directory — owner only (SSH will refuse to work otherwise)
chmod 600 ~/.ssh/id_rsaPrivate key — owner read/write only
chmod 644 ~/.ssh/id_rsa.pubPublic key — readable by all
chmod 600 ~/.ssh/authorized_keysAuthorized keys file
chmod 644 ~/.ssh/known_hostsKnown hosts file
chmod 600 ~/.ssh/configSSH client config file

Shared Directory for a Team

CommandPurpose
groupadd devteamCreate a shared group
usermod -aG devteam aliceAdd alice to the group
mkdir /srv/projectCreate shared directory
chown root:devteam /srv/projectAssign group ownership
chmod 2775 /srv/projectSGID + owner full + group full + others rx
Why SGID on shared directories? Without SGID, files created inside /srv/project inherit the creator’s primary group — so alice’s files belong to alice and bob’s files belong to bob. With SGID set, all new files automatically inherit the devteam group, so everyone in the group can read and write them.

FAQ

What does execute permission mean on a directory?
On a directory, execute (x) means the ability to enter the directory and access files inside it — it is also called the “search” bit. Without execute on a directory you cannot cd into it, cannot access files inside it, and cannot traverse it in a path. You need execute on every directory in a file’s path to access the file. Read (r) on a directory means you can list its contents (ls). Write (w) means you can create, delete, and rename files inside it.
I own a file but cannot delete it. Why?
File deletion is controlled by the parent directory’s write permission, not the file’s own permissions. To delete a file you need write (w) and execute (x) on the directory that contains it. If the directory has the sticky bit set (t), you can only delete files you own — even if you have write permission on the directory. This is why you can’t delete other users’ files in /tmp.
What is the difference between chmod 755 and chmod u=rwx,go=rx?
They produce identical results — both set owner to rwx, group and others to rx. The numeric form is shorter and common in scripts and documentation. The symbolic form is more readable and safer for incremental changes: chmod +x script.sh adds execute without touching other bits, while chmod 755 script.sh sets all bits explicitly, potentially removing permissions you didn’t intend to change.
How do I safely apply permissions recursively without making all files executable?
Use two separate find commands: find /path -type d -exec chmod 755 {} \; for directories and find /path -type f -exec chmod 644 {} \; for files. Alternatively, use capital X: chmod -R a+rX /path — capital X adds execute only to directories and files that already have execute set for anyone, leaving regular files non-executable. Never use chmod -R 755 /path on a web directory — it makes every file executable.
Why does SSH refuse to connect when my key permissions are “too open”?
SSH deliberately refuses to use private keys that are accessible by other users — this is a security feature. The required permissions are: 700 on ~/.ssh, 600 on private keys (id_rsa, id_ed25519), and 600 on authorized_keys. If group or others have any read/write access to these files, SSH will display “Permissions 0644 for ‘id_rsa’ are too open” and refuse to use the key. Fix with chmod 600 ~/.ssh/id_rsa.
What is the difference between SUID and sudo?
SUID is a file permission bit — when set on an executable, it runs with the file owner’s UID regardless of who executes it. No configuration needed, no logging, no restrictions on what the binary can do. sudo is a program that allows specific users to run specific commands as another user (usually root), controlled by /etc/sudoers with full logging. For granting elevated access, always prefer sudo over SUID — sudo provides auditing, granular control, and can be revoked without touching file permissions.