The Ultimate Guide to Linux File Permissions: chmod, chown & More

Linux file permissions define who can read, modify, execute, or access files and directories. They affect everyday server work, including deployments, SSH keys, scripts, uploads, backups, logs, and shared folders.

This guide is for developers, admins, DevOps beginners, website owners, and anyone working with Linux through the terminal. You only need command line access and basic tools such as ls, chmod, chown, chgrp, and find.

If you manage websites, applications, scripts, or databases on a Linux VPS server, understanding file permissions helps you find the real cause of access issues instead of relying on unsafe fixes like chmod 777.

Understanding the Linux Permission Model

Linux permissions are built around three access levels: user, group, and others. The user is the file or directory owner. The group allows several accounts to share controlled access. Others covers everyone else on the system.

This model is simple, but practical for real server work. A deployment user can manage application files, a web server group can read what it needs, and unrelated users can be blocked from changing sensitive data.

Linux also uses three core permission types: read, write, and execute. They look straightforward, but they behave differently for files and directories, which is where many permission mistakes begin.

Users, Groups, and Others, Read, Write, Execute — What Each Permission Does

Every file and directory has an owner and a group. When access is requested, Linux checks permissions in this order: owner first, then group, then others. It uses only the first matching category, so permissions are not combined.

Each category can have read, write, and execute access. For files, read means viewing contents, write means editing, and execute means running the file as a script or program. For directories, read means listing items, write means creating or deleting items, and execute means entering the directory.

This last point matters a lot. Without execute permission on a directory, a user may see its name but still fail to access files inside. That is why permission checks should include the full path, not just the final file.

How to Check File Permissions in Linux

The most common command for checking Linux file permissions is:

ls -l

A typical output line may look like this:

-rwxr-xr-- 1 deploy www-data 2048 May 8 app.sh

The first character shows the file type. A regular file starts with -, while a directory starts with d. The next nine characters show permissions for the owner, group, and others. In this example, rwx belongs to the owner, r-x belongs to the group, and r-- belongs to others.

The owner is deploy, and the group is www-data. This means the deploy user receives the owner permissions, while users in the www-data group receive the group permissions. Everyone else receives the others permissions.

Reading the Output of ls -l, Octal vs Symbolic Notation

The permission string always follows the same structure. The first character identifies the object type. The next three characters belong to the owner. The next three belong to the group. The final three belong to others.

For example:

drwxr-xr-x

This is a directory because it starts with d. The owner can read, write, and enter it. The group can read and enter it. Others can also read and enter it, but they cannot create or delete files inside it.

For a regular file, you may see:

-rw-r--r--

This means the owner can read and write, while the group and others can only read. This is a common permission pattern for public website files, static assets, and documents that should be visible but not editable by everyone.

Linux permissions can be written in symbolic notation or octal notation. Symbolic notation uses letters such as r, w, and x. Octal notation uses numbers, where read equals 4, write equals 2, and execute equals 1.

The numbers are added together for each identity level. Read and write become 6. Read and execute become 5. Read, write, and execute become 7. No permissions become 0. A value such as 755 means the owner gets 7, the group gets 5, and others get 5. In symbolic form, this becomes rwxr-xr-x. A value such as 644 means the owner can read and write, while the group and others can only read.

How to Change File Permissions with chmod

The chmod command changes permissions for files and directories. It supports two formats: symbolic mode and numeric mode.

Symbolic mode is best for small changes, such as adding execute permission to a script without changing anything else. Numeric mode is faster when you already know the exact permission value, such as 755 for directories or 644 for regular files.

Common Permission Values Explained: Symbolic Mode (chmod u+x, chmod go-w), Numeric Mode (chmod 755, chmod 644)

Symbolic mode uses identity letters, operators, and permission letters. The identity letters are u for user, g for group, o for others, and a for all. The operators are + to add a permission, - to remove a permission, and = to set permissions exactly.

For example:

chmod u+x script.sh

This adds execute permission for the owner. It is commonly used when a shell script exists but cannot be run directly.

Another useful command is:

chmod go-w file.txt

This removes write permission from the group and others. It is useful when a file should remain readable but should only be editable by its owner.

Numeric mode sets the full permission value in one command. For example:

chmod 755 script.sh

This allows the owner to read, write, and execute the file, while the group and others can read and execute it.

Another common command is:

chmod 644 index.html

This allows the owner to edit the file, while the group and others can only read it. This is a common setup for website files.

Permission value 

Common use 

What it means 

Safety note 

755

Directories and executable scripts 

The owner can read, write, and execute. Group and others can read and execute 

Good for directories that must be accessible, but not writable by everyone 

644

Regular website files, documents, public readable files 

The owner can read and write. Group and others can read only 

Good default for many web files and static assets 

777

Almost never appropriate for production 

Everyone can read, write, and execute 

Dangerous because any user or process can modify the item 

The value 777 deserves a strict warning. It gives complete access to everyone on the system. On a public server, shared environment, or Rocky Linux VPS, this can allow vulnerable scripts, compromised users, or malicious processes to modify files that should be protected. In most cases, chmod 777 does not solve the real problem. It only hides a deeper issue with ownership, group membership, service users, or application configuration.

Changing File Ownership with chown and chgrp

Permissions define what the owner, group, and others can do. Ownership defines who the owner and group actually are. This is why chmod and chown solve different problems.

The basic syntax for changing the owner is:

chown user file

To change both owner and group, use:

chown user:group file

To change only the group, use:

chown :group file

You can also change only the group with:

chgrp group file

For example:

chown deploy:www-data /var/www/example.com

This makes deploy the owner and www-data the group. In a web project, this can allow the deployment user to manage files while giving the web server controlled group access.

Recursive ownership changes are possible with:

chown -R user:group directory

Recursion should be used carefully because it changes ownership for every item inside the target directory. Before running recursive ownership changes, confirm the path with pwd, inspect the target with ls, and make sure you are not applying changes to a broad system directory by mistake.

The practical difference is simple. Use chmod when the correct user owns the file but the access level is wrong. Use chown or chgrp when the wrong user or group owns the file.

Recursive Permission Changes

Recursive permission changes apply a rule to an entire directory tree. They are useful during deployments, migrations, backups, and cleanup tasks, but they are also one of the fastest ways to create permission problems.

A risky command looks like this:

chmod -R 755 /var/www/example.com

This applies 755 to every file and directory. Directories often need execute permission because users and services must enter them, but ordinary files usually do not need execute permission. Applying the same value to everything can make regular files executable without reason.

A safer approach is to use find and apply separate permissions for directories and files:

find /var/www/example.com -type d -exec chmod 755 {} \;

find /var/www/example.com -type f -exec chmod 644 {} \;

This pattern is common for web projects. Directories remain accessible, regular files remain readable, and only the owner can modify content. When applications run on BlueVPS servers, this predictable structure also makes troubleshooting easier because files and directories follow different rules for a clear reason.

Recursive commands should always be reviewed before execution. A small typo in a path can change thousands of files. When working on production systems, it is better to test the target with find path -type f | head or find path -type d | head before applying changes.

Special Permissions: SUID, SGID, and Sticky Bit

Linux also supports special permission bits that change normal access behavior. They are useful in specific cases, but they should be applied carefully, especially on production systems.

SUID lets an executable run with the permissions of the file owner. This can be powerful because the program may perform actions that the current user normally cannot, so SUID should only be used when there is a clear reason.

SGID works with files and directories. On files, it runs an executable with the permissions of the file group. On directories, it makes new files inherit the directory group, which is helpful for shared project folders.

The sticky bit is often used on shared writable directories such as /tmp. It lets users create files but prevents them from deleting files owned by others.

Common examples include:

chmod u+s file

chmod g+s directory

chmod +t directory

Special permissions are not everyday settings for most website files. They are best used when there is a specific access control requirement, especially on production systems.

Troubleshooting Permission Errors

Permission errors are not always caused by the final file. Ownership, parent directories, service users, SSH key rules, filesystem mount options, and security systems such as SELinux or AppArmor can all be involved.

A good troubleshooting process starts with the active user, then checks the target file, then checks every parent directory in the path. This matters because a file can have correct permissions while one parent directory still blocks access.

Error or symptom 

Likely cause 

Practical solution 

Permission denied 

The active user lacks the required read, write, or execute permission 

Check whoami, run ls -l, then adjust the smallest necessary permission or ownership value

Script does not run 

The file lacks execute permission 

Run chmod u+x script.sh, then execute it with ./script.sh

Cannot enter directory 

The directory lacks execute permission 

Add execute permission for the correct user or group 

403 Forbidden in web server 

The web server user cannot access files or parent directories 

Check ownership, group access, and directory permissions across the full path 

SSH private key is rejected 

Private key permissions are too open 

Run chmod 600 ~/.ssh/id_rsa and confirm ownership of the .ssh directory

Application cannot upload files 

The service user lacks write access to the upload directory 

Change owner or group for the upload directory, then grant write access only where needed

chmod changes do not help 

Wrong owner, parent directory issue, SELinux, AppArmor, or mount restrictions 

Use namei -l path, check the service user, then inspect security policy if enabled

On a US-based VPS, this kind of troubleshooting usually happens remotely through SSH, so a careful sequence saves time. Confirm the user, inspect the target file, check parent directories, verify ownership, then apply the narrowest safe change.

Quick Reference — chmod Cheat Sheet

Use this quick reference table when you need a fast command reminder for everyday Linux permission tasks, from checking access rights to fixing ownership and applying safe default values for files and directories.

Task

Command

Show file permissions 

ls -l file

Show permissions across a full path 

namei -l /path/to/file

Make a script executable for the owner 

chmod u+x script.sh

Remove write access from group and others 

chmod go-w file

Set standard file permissions 

chmod 644 file

Set standard directory permissions 

chmod 755 directory

Lock a private SSH key 

chmod 600 ~/.ssh/id_rsa

Change file owner 

chown user file

Change owner and group 

chown user:group file

Change only group 

chgrp group file

Apply 755 only to directories 

find path -type d -exec chmod 755 {} \;

Apply 644 only to files 

find path -type f -exec chmod 644 {} \;

Add sticky bit to a shared directory 

chmod +t directory

Add SGID to a shared project directory 

chmod g+s directory

FAQ

Is chmod 777 dangerous?

Yes. chmod 777 gives everyone full access, so it can expose files to unwanted changes, deletion, or attacks. Use it only for short testing, never as a permanent fix.

 

How do I make a file executable in Linux?

Use chmod u+x filename. For scripts, check the interpreter line, such as #!/bin/bash, then run it with ./filename.

 

What is the difference between chmod and chown?

chmod changes permissions. chown changes ownership. If the owner or group is wrong, chmod alone may not fix access.

 

What does chmod 755 mean?

chmod 755 gives the owner full access, while the group and others can read and execute. It is common for directories and scripts.

 

What does chmod 644 mean?

chmod 644 lets the owner read and edit, while the group and others can only read. It is common for website files and documents.

 

Why do I get Permission denied after changing permissions?

The issue may be ownership, parent directories, the service user, SELinux, or AppArmor. Check with whoami, ls -l, and namei -l.

 

Should files and directories have the same permissions?

Usually no. A safe web pattern is 755 for directories, 644 for files, and 600 for private keys.

Blog