Linux File Permissions Explained: chmod, chown and umask for Developers
By Álvaro G.V. · Updated
Linux file permissions control who can read, write, and execute files. Get them wrong and you either lock yourself out of your own files or leave sensitive data readable by anyone on the server. This guide explains the permission model from first principles.
If you'd rather click checkboxes than do octal arithmetic, the chmod calculator converts between rwxr-xr-x and 755 as you go.
The Permission Model
Every file and directory on a Linux system has three types of permissions applied to three groups of users:
| Group | Who it applies to |
|---|---|
| Owner (u) | The user who owns the file |
| Group (g) | Users who are members of the file's assigned group |
| Others (o) | Everyone else on the system |
Each group gets three independent permission bits:
- Read (r) — view the file contents / list the directory
- Write (w) — modify the file / create or delete files in the directory
- Execute (x) — run the file as a program / enter (traverse) the directory
Reading the Symbolic Notation
When you run ls -la, you see permissions in symbolic notation:
-rwxr-xr-x 1 alice devs 4096 Mar 22 deploy.sh
drwxr-xr-x 2 alice devs 4096 Mar 22 scripts/The first character is the file type (- for regular file, d for directory, l for symlink). The next 9 characters are three groups of three permission bits:
rwx r-x r-x
│ │ └── Others: read, no write, execute
│ └─────── Group: read, no write, execute
└─────────── Owner: read, write, executeUnderstanding Octal Notation
Each permission bit is a binary 1 (enabled) or 0 (disabled). The three bits in each group map to a single octal digit: read = 4, write = 2,execute = 1. Add the values of enabled bits to get the digit.
| Binary | Symbolic | Octal | Meaning |
|---|---|---|---|
| 111 | rwx | 7 | read + write + execute |
| 110 | rw- | 6 | read + write only |
| 101 | r-x | 5 | read + execute only |
| 100 | r-- | 4 | read only |
| 000 | --- | 0 | no permissions |
So chmod 755 means: owner=7 (rwx), group=5 (r-x), others=5 (r-x).
Common Permission Patterns
| Octal | Symbolic | Use case |
|---|---|---|
755 | rwxr-xr-x | Executables, binaries, shell scripts (including ones run by cron), directories |
644 | rw-r--r-- | Config files, web assets, documentation |
600 | rw------- | SSH private keys, .env files, secret credentials |
700 | rwx------ | ~/.ssh/ directory, private script directories |
664 | rw-rw-r-- | Shared files within a team group |
400 | r-------- | Immutable backups, read-only reference files |
Each of these has its own page in common chmod modes explained, for example 755, 644, 600 and the special modes 4755 (setuid) and 1777 (sticky bit).
chmod, chown, and chgrp
# Change permissions
chmod 755 deploy.sh # Set exact permissions (octal)
chmod u+x deploy.sh # Add execute for owner only
chmod go-w secret.conf # Remove write from group and others
chmod -R 755 /var/www/html # Recursive (use carefully)
# Change owner
chown alice deploy.sh
chown alice:devs deploy.sh # Owner and group simultaneously
# Change group
chgrp devs shared-config.ymlumask: Default Permissions
umask is a mask that subtracts permissions from the default when new files and directories are created. The typical default is 022, meaning:
- New files: 666 (default) − 022 = 644 (rw-r--r--)
- New directories: 777 (default) − 022 = 755 (rwxr-xr-x)
A stricter umask like 027 would give 640 files and 750 directories — no read access for others. Set in ~/.bashrc or /etc/profile:
umask 027 # More restrictive default permissionsUse the Chmod Calculator to visually build permission sets and instantly see the octal value and symbolic notation.
Frequently Asked Questions
Why does SSH refuse to use my private key and say 'permissions are too open'?▾
SSH enforces strict permissions on private keys for security. If your key file (~/.ssh/id_rsa) has permissions more permissive than 600 (rw-------), SSH will refuse to use it with an 'Unprotected private key file' error. Fix: chmod 600 ~/.ssh/id_rsa. The ~/.ssh directory itself should be 700 (drwx------). This prevents other users on the system from reading your private key.
What is setuid, setgid, and sticky bit?▾
These are three special permission bits beyond the basic rwx. setuid (s in place of owner execute): when set on an executable, it runs as the file's owner, not the user who executed it — used by /usr/bin/passwd to temporarily get root privileges. setgid (s in place of group execute): on an executable, runs as the file's group; on a directory, new files inherit the directory's group. sticky bit (t in place of other execute): on a directory, only the file owner (or root) can delete files — used on /tmp to prevent users deleting each other's temp files.
How do I find files with dangerous permissions?▾
Use find with the -perm flag. Find world-writable files: 'find / -type f -perm -002 2>/dev/null'. Find setuid binaries: 'find / -type f -perm -4000 2>/dev/null'. Find files with no owner: 'find / -nouser 2>/dev/null'. These are common security audit checks. On a production server, world-writable files or unexpected setuid binaries are red flags that warrant investigation.
Related guides
Number Systems for Developers: Binary, Octal, Decimal and Hex Explained
Why programmers use binary, octal, and hexadecimal — with practical examples from bit manipulation, color codes, file permissions, and memory addresses.
.env Files and Environment Variables Explained
Environment variables and .env files are how modern applications manage configuration across environments. Learn how they work, how to use dotenv, and how to keep secrets out of your codebase.
Cron Syntax Explained: */15 * * * * and Other Examples
Understand cron syntax with real examples. Learn how to schedule jobs with minute, hour, day, month, and weekday fields — with a handy reference table.