How to Calculate Chmod Permissions (Easy Guide)
This guide has a free tool → Open Chmod Calculator
# How to Calculate Chmod Permissions (Easy Guide)
What Is Chmod?
chmod stands for "change mode" and it is the Unix and Linux command used to set file and directory permissions. Every file on a Unix system has three sets of permissions that control who can read it, write to it, or execute it.
If you have ever deployed a web app, configured a server, SSH'd into a remote machine, or written a shell script, you have almost certainly run something like this:
chmod 755 deploy.sh
chmod 644 config.json
chmod 600 ~/.ssh/id_rsaThose numbers are not arbitrary. They encode a complete set of permissions in a compact, three-digit format. Once you understand the logic, calculating chmod values becomes fast and intuitive. This guide explains exactly how it works, covers the permissions you will use most often, shows you what can go wrong, and introduces both numeric and symbolic notation.
---
The Foundation: Three Groups, Three Permissions
Every file on a Unix or Linux system has permissions split across three categories of users, and three types of access.
The Three User Categories
Owner (u): The user who owns the file. Typically the user who created it, or the one set via chown. The owner has the most control and usually gets the most permissive settings.
Group (g): Every file belongs to a group. Users who are members of that group get the group permissions. On many systems, a user's primary group has the same name as their username, but groups can contain multiple users for shared access control.
Others (o): Everyone else on the system who is not the owner and not a member of the file's group. This is what "world" permissions means.
The Three Permission Types
Read (r): For files, read permission means the user can view the file's contents. For directories, read means the user can list the directory's contents with ls.
Write (w): For files, write means the user can modify or delete the file. For directories, write means the user can create, rename, or delete files within the directory. Note: you need write permission on a directory to delete a file in it, even if you own the file.
Execute (x): For files, execute means the user can run the file as a program or script. For directories, execute (sometimes called "search" permission) means the user can cd into the directory and access files within it. Without execute on a directory, even if you have read permission, you cannot access the files inside.
The Octal Values
Each permission type has an assigned numeric value:
| Permission | Symbol | Octal Value |
|---|---|---|
| Read | r | 4 |
| Write | w | 2 |
| Execute | x | 1 |
| No permission | - | 0 |
These values were chosen specifically so that any combination of permissions produces a unique sum. You cannot create an ambiguous total with these three numbers.
---
How the Three-Digit Number Works
The chmod number is three digits. Each digit represents the permissions for one user category, in order: Owner, Group, Others.
Each digit is calculated by adding up the values of the permissions you want to grant for that category:
Digit = Read(4) + Write(2) + Execute(1)Since each permission is a power of 2 (4, 2, 1), every sum from 0 to 7 uniquely encodes a specific combination:
| Digit | Permissions | Symbolic |
|---|---|---|
| 0 | No permissions | --- |
| 1 | Execute only | --x |
| 2 | Write only | -w- |
| 3 | Write + Execute | -wx |
| 4 | Read only | r-- |
| 5 | Read + Execute | r-x |
| 6 | Read + Write | rw- |
| 7 | Read + Write + Execute | rwx |
So when you write chmod 755:
- 7 (Owner): 4+2+1 = Read, Write, Execute
- 5 (Group): 4+1 = Read, Execute (no write)
- 5 (Others): 4+1 = Read, Execute (no write)
In symbolic notation, that is rwxr-xr-x.
And chmod 644:
- 6 (Owner): 4+2 = Read, Write (no execute)
- 4 (Group): 4 = Read only
- 4 (Others): 4 = Read only
Symbolic: rw-r--r--
---
Visualizing the Bit Pattern
It helps to see permissions as a 9-character string. Each character is either the permission letter or a dash for "no permission":
rwxr-xr-x
^^^ ^^^ ^^^
| | |
| | Others: r-x
| Group: r-x
Owner: rwxReading ls -la output uses exactly this format:
$ ls -la
-rwxr-xr-x 1 alice developers 4096 Feb 13 10:30 deploy.sh
-rw-r--r-- 1 alice developers 1024 Feb 13 10:25 config.json
-rw------- 1 alice alice 512 Jan 01 09:00 .env
drwxr-xr-x 2 alice developers 4096 Feb 10 14:00 scripts/The first character is the file type (- for regular file, d for directory, l for symlink). Characters 2-10 are the nine permission bits.
---
Common Chmod Values
These are the values you will reach for most often:
755 - Standard for Executables and Directories
chmod 755 deploy.sh
chmod 755 /var/www/html
chmod -R 755 /var/www/html # -R applies recursively to everything insideWho can do what:
- Owner: read, write, execute (full access)
- Group: read, execute (can run and view, cannot modify)
- Others: read, execute (same as group)
Why it is the standard for directories: Directories need the execute bit to allow users to cd into them and access their contents. 755 means your web server process (which typically runs as www-data or nginx, part of the file's group or as "others") can read and traverse the directory without being able to modify it.
Why it is the standard for scripts: Web hooks, deployment scripts, and shell scripts that need to be runnable by the system or other users should be 755.
644 - Standard for Regular Files
chmod 644 index.html
chmod 644 style.css
chmod 644 config.json
chmod -R 644 /var/www/html/assetsWho can do what:
- Owner: read, write (can modify)
- Group: read only
- Others: read only
Why it is the standard for web files: Your web server needs to read your HTML, CSS, JavaScript, and image files to serve them. The server process should not be able to modify them. 644 gives you exactly that. You can edit the files as the owner, but the server only reads.
600 - Private Files
chmod 600 ~/.ssh/id_rsa
chmod 600 .env
chmod 600 database-credentials.confWho can do what:
- Owner: read, write (full access)
- Group: no permissions
- Others: no permissions
Why it is essential for secrets: SSH private keys, environment files with database passwords and API secrets, and any file containing credentials should be 600. The operating system enforces this: SSH itself will refuse to use a private key if its permissions are too permissive.
# SSH will give this error if your key is too open:
$ ssh -i my-key.pem user@host
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'my-key.pem' are too open.
It is required that your private key files are NOT accessible by others.
Bad permissions: ignore key: my-key.pemFix: chmod 600 my-key.pem
700 - Private Executables and Directories
chmod 700 ~/private-scripts/
chmod 700 ~/bin/internal-backup.shWho can do what:
- Owner: read, write, execute (full access)
- Group: no permissions
- Others: no permissions
Use this for personal scripts that should not be visible or runnable by anyone else on the system, and for private directories where the contents should be completely restricted.
750 - Owner Full, Group Read/Execute
chmod 750 /var/www/private-apiWho can do what:
- Owner: read, write, execute (full access)
- Group: read, execute (can traverse and read, cannot write)
- Others: no permissions at all
This is useful when you want a specific group (like developers or www-data) to have access, but everyone else should be completely excluded.
777 - Full Access for Everyone
chmod 777 /tmp/shared-upload-folderWho can do what:
- Owner: read, write, execute
- Group: read, write, execute
- Others: read, write, execute
This is almost never appropriate in production. Any user on the system can read, modify, or delete a 777 file. If a web server process gets compromised under 777 permissions, the attacker can overwrite your files. If you are setting 777 to "fix" a permissions error, something else is wrong and 777 is hiding the real problem.
444 - Read-Only for Everyone
chmod 444 important-reference.txt
chmod 444 legal-agreement.htmlWho can do what:
- Owner: read only
- Group: read only
- Others: read only
Nobody can modify the file, including the owner. Useful for files you want to protect from accidental modification. Note that the owner can still delete the file from its directory if they have write permission on the directory.
---
Quick Reference Table
| Octal | Symbolic | Owner | Group | Others | Common Use Case |
|---|---|---|---|---|---|
| 777 | rwxrwxrwx | Full | Full | Full | Avoid in production |
| 755 | rwxr-xr-x | Full | Read+Exec | Read+Exec | Executables, directories |
| 750 | rwxr-x--- | Full | Read+Exec | None | Group-access directories |
| 700 | rwx------ | Full | None | None | Private scripts |
| 644 | rw-r--r-- | Read+Write | Read | Read | Web files, documents |
| 640 | rw-r----- | Read+Write | Read | None | Config files, group-restricted |
| 600 | rw------- | Read+Write | None | None | SSH keys, .env files |
| 444 | r--r--r-- | Read | Read | Read | Read-only archives |
| 400 | r-------- | Read | None | None | Highly sensitive keys |
---
Symbolic Notation: The Alternative Syntax
You can also use symbolic notation with chmod. Instead of specifying the complete permission set as a number, you specify changes to make relative to the current state. This has real advantages in some situations.
Symbolic Operators and Targets
Targets:
u= user (owner)g= groupo= othersa= all (equivalent to ugo)
Operators:
+= add permission-= remove permission== set exact permission (replaces current)
Examples
# Add execute permission for the owner only
chmod u+x script.sh
# Remove write permission for group and others
chmod go-w sensitive-file.txt
# Add read permission for all
chmod a+r public-document.txt
# Set exact permissions (same as chmod 755)
chmod u=rwx,go=rx deploy.sh
# Remove all permissions for others
chmod o= private.txt
# Add execute for everyone if the file is already executable by anyone (X, capital X)
# Capital X only adds execute to directories, or files that already have some execute bit
chmod a+X directory-or-fileWhen to Prefer Symbolic Notation
Making incremental changes: If you just need to add execute permission without changing anything else, chmod u+x script.sh is clearer and safer than calculating the full new octal value.
When you do not know the current state: chmod g-w file removes write from group regardless of current permissions. The octal equivalent requires you to first check what permissions exist.
Readability: chmod go-w is self-documenting in a way that chmod 644 is not.
Numeric notation advantages: When you want to set the complete, exact permission set in one shot, numeric is faster and leaves no ambiguity. Deployment scripts typically use numeric because you know exactly what you want.
---
How Permissions Apply to Directories vs. Files
This distinction trips up a lot of developers:
Execute on Directories
The execute bit on a directory does not mean "run this as a script." It means the user can cd into the directory and access its contents. It is sometimes called the "search" bit. Without execute on a directory:
# If /var/www has permissions 644:
$ ls /var/www # Works (read permission)
$ cd /var/www # Permission denied (no execute bit)
$ cat /var/www/index.html # Permission denied (cannot traverse)This is why directories typically need 755 rather than 644.
Write on Directories
Write permission on a directory controls whether users can create, rename, or delete files inside it. This is separate from permissions on the files themselves:
# You can delete a file you DO NOT own if you have write on its directory
# You CANNOT delete a file if you lack write on its directory, even if you own it
# The sticky bit (chmod 1777 /tmp) prevents this:
# Prevents users from deleting files owned by others, even in world-writable directoriesThe Sticky Bit
The /tmp directory on Linux systems is world-writable (so anyone can create temp files) but has the sticky bit set. This means users can only delete their own files, not files owned by others:
$ ls -la /tmp
drwxrwxrwt 10 root root 4096 Feb 13 12:00 .
^
Sticky bit: 't' instead of 'x' for others' executeSet it with: chmod +t /tmp/shared-folder or chmod 1777 /tmp/shared-folder
---
Setting Permissions in Practice
Recursively Setting Permissions
When setting permissions on a directory tree, you often need to apply different permissions to directories vs. files. Directories need execute to be traversable; most files do not need execute.
# Set all directories to 755 and all files to 644 in one shot
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;This is more precise than chmod -R 755 /var/www/html, which would set execute on all files (you rarely want that).
Deployment Script Pattern
A typical deployment script permission setup:
#!/bin/bash
PROJECT_DIR="/var/www/myapp"
# Directories: traversable but not writable by others
find "$PROJECT_DIR" -type d -exec chmod 755 {} \;
# Regular files: readable but not writable by others
find "$PROJECT_DIR" -type f -exec chmod 644 {} \;
# Shell scripts: need to be executable
chmod 755 "$PROJECT_DIR/scripts/"*.sh
# Environment and secrets: owner only
chmod 600 "$PROJECT_DIR/.env"
chmod 600 "$PROJECT_DIR/config/secrets.json"
# Uploads directory: writable by web server
chmod 775 "$PROJECT_DIR/uploads"
chown -R www-data:www-data "$PROJECT_DIR/uploads"SSH Setup
SSH has strict requirements on file permissions. Here is the complete setup:
# The .ssh directory itself
chmod 700 ~/.ssh
# Private key: owner read/write only
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
# Public key: owner read/write, others read
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/id_ed25519.pub
# Authorized keys file
chmod 600 ~/.ssh/authorized_keys
# Config file
chmod 600 ~/.ssh/config
# Known hosts
chmod 644 ~/.ssh/known_hostsIf these permissions are wrong, SSH either refuses to connect or silently ignores your key.
Web Server Configuration
Nginx and Apache run as a system user (commonly www-data or nginx). Files need to be readable by that user:
# Set ownership of web files to your user, with web server group
chown -R alice:www-data /var/www/html
# Directories: owner full, group traverse, others nothing
find /var/www/html -type d -exec chmod 750 {} \;
# Files: owner read/write, group read, others nothing
find /var/www/html -type f -exec chmod 640 {} \;This is more locked down than the typical 755/644 setup and is appropriate for applications with sensitive content.
---
Common Chmod Mistakes and How to Fix Them
Mistake 1: Using 777 in Production
Why it happens: A "permission denied" error appears, 777 makes it go away, and the developer moves on.
The problem: Every process running on the system can now modify your files. If your web server is compromised, the attacker can write new files. PHP scripts running with insufficient isolation can overwrite your application code.
The fix: Figure out what user needs access, and grant permissions only to that user or group:
# Instead of this:
chmod 777 /var/www/uploads
# Do this: own it by the web server user
chown www-data:www-data /var/www/uploads
chmod 755 /var/www/uploads
# Or use a shared group:
chgrp www-data /var/www/uploads
chmod 775 /var/www/uploads # Group can write, others cannotMistake 2: Setting 644 on Directories
Why it happens: Running chmod -R 644 on a directory tree, intending to set all files to 644, also sets the directories to 644.
The problem: 644 on a directory means no execute bit, which means no one can cd into it or access its contents. Your web server returns 403 Forbidden even though the files themselves have correct permissions.
The fix: Apply different permissions to files and directories:
find /path -type d -exec chmod 755 {} \; # Directories get 755
find /path -type f -exec chmod 644 {} \; # Files get 644Mistake 3: Permissions Too Loose on Secret Files
Why it happens: .env files or credential files are committed with default permissions (644), which makes them readable by all users on the system.
The problem: Any other user or process on the machine can read your database password, API keys, and secrets.
The fix:
chmod 600 .env
chmod 600 config/credentials.json
chmod 600 .pgpassAnd consider adding a check to your deployment script or CI pipeline.
Mistake 4: Forgetting to Set Execute on Scripts
Why it happens: You write a shell script and try to run it, getting "Permission denied" even though you own it.
The fix:
chmod u+x script.sh # Add execute for owner
./script.sh # Now it runsOr use bash script.sh to run it through the interpreter without the execute bit, though this is less clean.
Mistake 5: Wrong Ownership After sudo Operations
Why it happens: You run a command with sudo that creates files, and they end up owned by root instead of your application user.
The fix:
# Check who owns the files
ls -la /var/www/html
# Fix ownership
sudo chown -R alice:www-data /var/www/html---
Advanced: Special Permission Bits
Beyond the standard rwx permissions, Unix has three special bits:
Setuid (s on user execute position)
When set on an executable, the program runs with the permissions of the file's owner rather than the user running it. This is how passwd lets regular users modify /etc/shadow (owned by root).
chmod 4755 program # Setuid: runs as owner
# Shows as: rwsr-xr-xSetgid (s on group execute position)
When set on an executable, the program runs with the group permissions of the file's group. When set on a directory, new files created inside inherit the directory's group.
chmod 2755 program # Setgid on file: runs as group
chmod 2775 shared-dir # Setgid on directory: new files inherit group
# File shows as: rwxr-sr-x
# Directory shows as: rwxrwsr-xSticky Bit (t on others execute position)
When set on a directory, only the file's owner can delete or rename files within it, even if others have write permission. This is used on shared directories like /tmp.
chmod 1777 /tmp/shared # World-writable but protected
# Shows as: rwxrwxrwtThe full four-digit octal representation: chmod 4755 (setuid), chmod 2755 (setgid), chmod 1755 (sticky).
---
Reading ls -la Output
Understanding ls -la output is essential for auditing permissions:
$ ls -la /etc/nginx/
total 72
drwxr-xr-x 8 root root 4096 Feb 10 09:15 .
drwxr-xr-x 89 root root 4096 Feb 10 09:10 ..
drwxr-xr-x 2 root root 4096 Feb 10 09:15 conf.d
-rw-r--r-- 1 root root 1462 Feb 10 09:15 nginx.conf
-rw-r----- 1 root root 664 Feb 10 09:15 nginx.conf.secret
lrwxrwxrwx 1 root root 27 Feb 10 09:15 sites-enabled -> /etc/nginx/sites-availableBreaking down -rw-r--r-- 1 root root 1462 Feb 10 09:15 nginx.conf:
| Field | Value | Meaning |
|---|---|---|
| File type | - | Regular file (d=directory, l=symlink) |
| Owner perms | rw- | Read + Write, no execute |
| Group perms | r-- | Read only |
| Others perms | r-- | Read only |
| Links | 1 | Number of hard links |
| Owner | root | Owned by root user |
| Group | root | Belongs to root group |
| Size | 1462 | Size in bytes |
| Modified | Feb 10 09:15 | Last modification time |
| Name | nginx.conf | Filename |
---
Use the ToolBox Chmod Calculator
Remembering octal math is fine once you have done it many times, but when you are setting up a new server under time pressure and second-guessing your mental arithmetic, a visual calculator prevents mistakes.
The Chmod Calculator on ToolBox lets you:
- Toggle read, write, and execute checkboxes for owner, group, and others
- See the octal number and symbolic notation update in real time as you check boxes
- Start from common presets like 755, 644, 600, and 777
- Copy the full
chmodcommand, complete with the number and the placeholder for your filename - Understand what you are setting before you run it
No signup, no ads, runs entirely in your browser. The next time you are writing a deployment script, setting up SSH keys on a new server, or just triple-checking a permission value before running it in production, open the Chmod Calculator and make sure you get it right the first time.
Understanding permissions is one of those foundational Unix skills that pays dividends for years. Once the octal math clicks, you will never need to look it up again. And until it clicks, you will know exactly where to go for a quick sanity check.
Related Tools
Free, private, no signup required
JSON Formatter
JSON formatter and validator online - format, beautify, and validate JSON data instantly in your browser
Regex Tester
Free online regex tester - test and debug regular expressions with live matching and highlights
Text Diff Checker
Free online text diff checker - compare two texts and see the differences highlighted line by line
Code Formatter
Free online code formatter - beautify and format JavaScript, CSS, HTML, and more
You might also like
Want higher limits, batch processing, and AI tools?