A logo showing the text blog.marcnuri.com
Español
Home»Operations»Linux File Permissions: A Complete Guide

Recent Posts

  • Black Box vs White Box Testing: When to Use Each Approach
  • Fabric8 Kubernetes Client 7.4 is now available!
  • Kubernetes MCP Server Joins the Containers Organization!
  • MCP Tool Annotations: Adding Metadata and Context to Your AI Tools
  • Fabric8 Kubernetes Client 7.2 is now available!

Categories

  • Artificial Intelligence
  • Backend Development
  • Cloud Native
  • Engineering Insights
  • Frontend Development
  • JavaScript
  • Legacy
  • Operations
  • Personal
  • Pet projects
  • Quality Engineering
  • Tools

Archives

  • October 2025
  • September 2025
  • July 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • August 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • October 2019
  • September 2019
  • July 2019
  • March 2019
  • November 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • December 2017
  • October 2017
  • August 2017
  • July 2017
  • January 2017
  • December 2015
  • November 2015
  • December 2014
  • November 2014
  • October 2014
  • March 2014
  • February 2011
  • November 2008
  • June 2008
  • May 2008
  • April 2008
  • January 2008
  • November 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007

Linux File Permissions: A Complete Guide

2014-10-17 in Operations tagged Linux / BASH by Marc Nuri | Last updated: 2025-10-17

File permissions are one of the fundamental security features in Linux and Unix-like operating systems. They control who can read, write, or execute files and directories, forming the foundation of the multi-user security model that makes Linux systems secure and reliable.

In this guide, you'll learn how to view, understand, and modify file permissions, work with octal notation, handle special permissions, and troubleshoot common permission-related issues.

How to View File Permissions in Linux

The most common way to view file permissions is using the ls -l command:

bash
ls -l blog.marcnuri.com.txt

This produces output like:

-rw-r--r-- 1 marc users 1024 Oct 17 10:00 blog.marcnuri.com.txt

Let's break down what each part means:

  • -rw-r--r-- - The permission string (we'll decode this next)
  • 1 - Number of hard links
  • marc - Owner of the file
  • users - Group that owns the file
  • 1024 - File size in bytes
  • Oct 17 10:00 - Last modification date and time
  • blog.marcnuri.com.txt - File name

For more detailed information, you can use the stat command:

bash
stat blog.marcnuri.com.txt

This shows additional metadata including access and modification times, inode number, and both symbolic and octal permission representations.

Understanding the Permission String

The permission string -rw-r--r-- contains 10 characters. Let's decode them position by position:

Position 1 - File type:

  • - Regular file
  • d Directory
  • l Symbolic link
  • c Character device
  • b Block device

Positions 2-4 - Owner/user permissions:

  • r Read permission
  • w Write permission
  • x Execute permission
  • - Permission not granted

Positions 5-7 - Group permissions (same format as owner)

Positions 8-10 - Other/world permissions (same format as owner)

So -rw-r--r-- means:

  • It's a regular file (-)
  • Owner can read and write (rw-)
  • Group can only read (r--)
  • Others can only read (r--)

Permission Types Explained

The three basic permission types behave differently for files and directories:

Read Permission (r)

For files: Allows viewing the file's contents.

bash
cat blog.marcnuri.com.txt

For directories: Allows listing the directory's contents.

bash
ls /some/directory

Without read permission on a directory, you can't see what files it contains, even if you know their names.

Write Permission (w)

For files: Allows modifying the file's contents.

bash
echo "new content" > blog.marcnuri.com.txt

For directories: Allows creating, deleting, or renaming files within the directory.

Note that to delete a file, you need write permission on the directory, not the file itself.

Execute Permission (x)

For files: Allows running the file as a program or script.

bash
./script.sh

For directories: Allows accessing the directory (entering it with cd) and accessing files within it.

This is crucial: even if a directory has read permission, you need execute permission to cd into it or access files inside.

Permission Groups

Linux divides permissions into three groups:

Owner (User): The user who owns the file. Usually the person who created it, though ownership can be changed.

Group: A set of users who share access. Useful for team collaboration where multiple users need the same access level.

Others (World): Everyone else on the system who is not the owner or in the group.

This three-tier system provides flexible control over who can access your files while maintaining simplicity.

Octal Notation (Numeric Permissions)

Permissions can be represented as three-digit octal numbers, where each digit represents one permission group (owner, group, others).

Each permission type has a numeric value:

  • Read (r) = 4
  • Write (w) = 2
  • Execute (x) = 1
  • No permission = 0

You add these values together for each group:

SymbolicBinaryOctalMeaning
---0000No permissions
--x0011Execute only
-w-0102Write only
-wx0113Write and execute
r--1004Read only
r-x1015Read and execute
rw-1106Read and write
rwx1117Read, write, and execute

Common Permission Combinations

755 (rwxr-xr-x) - Executable files and directories

  • Owner can do anything
  • Group and others can read and execute
  • Common for scripts and programs

644 (rw-r--r--) - Regular files

  • Owner can read and write
  • Group and others can only read
  • Common for documents and configuration files

600 (rw-------) - Private files

  • Only owner can read and write
  • Nobody else has any access
  • Common for SSH keys and sensitive data

777 (rwxrwxrwx) - Full access for everyone

  • Everyone can do anything
  • Generally considered insecure
  • Avoid unless absolutely necessary

How to Change File Permissions (chmod)

The chmod command changes file permissions. It supports two modes: symbolic and numeric.

Symbolic Mode

Symbolic mode uses letters and operators to modify permissions:

bash
# Add execute permission for owner
chmod u+x script.sh

# Remove write permission for group
chmod g-w document.txt

# Set exact permissions for others (read only)
chmod o=r file.txt

# Add read and write for owner, remove execute for others
chmod u+rw,o-x file.txt

The format is: [who][operator][permissions]

Who:

  • u - User/owner
  • g - Group
  • o - Others
  • a - All (user, group, and others)

Operators:

  • + - Add permission
  • - - Remove permission
  • = - Set exact permission

Numeric Mode

Numeric mode uses octal values to set permissions:

bash
# Set permissions to rwxr-xr-x
chmod 755 script.sh

# Set permissions to rw-r--r--
chmod 644 document.txt

# Set permissions to rw-------
chmod 600 private-key.pem

Recursive Permissions

To change permissions for a directory and all its contents, use the -R flag:

bash
chmod -R 755 /path/to/directory

Be careful with recursive operations as they affect all files and subdirectories.

Directory vs File Permissions

Directories need different permission combinations than files to function properly.

For a directory to be usable, it typically needs execute permission. Without it, you cannot cd into the directory or access files inside it, even if you have read permission.

Common scenarios:

bash
# Directory with r-- (readable but not accessible)
ls /some/dir        # Works - shows file names
cd /some/dir        # Fails - cannot enter
cat /some/dir/file  # Fails - cannot access files

# Directory with --x (accessible but not readable)
ls /some/dir        # Fails - cannot list contents
cd /some/dir        # Works - can enter
cat /some/dir/file  # Works if you know the file name

For normal directory operation, you typically want both read and execute permissions (e.g., 755 or 750).

Special Permissions

Beyond the basic permissions, Linux supports three special permission types:

SetUID (SUID)

When set on an executable file, the program runs with the permissions of the file's owner, not the user who executed it.

bash
# Set SUID
chmod u+s /usr/bin/passwd
# Or using octal
chmod 4755 /usr/bin/passwd

The passwd command uses SUID because it needs to modify /etc/shadow (a root-owned file) even when run by regular users.

SUID appears as s in the owner's execute position:

-rwsr-xr-x 1 root root 68208 Oct 17 10:00 /usr/bin/passwd

SetGID (SGID)

For files: The file runs with the permissions of the file's group.

For directories: Files created within the directory inherit the directory's group, not the creator's primary group.

bash
# Set SGID
chmod g+s /shared/project
# Or using octal
chmod 2775 /shared/project

SGID appears as s in the group's execute position:

drwxrwsr-x 2 marc developers 4096 Oct 17 10:00 /shared/project

Sticky Bit

When set on a directory, only the file's owner, the directory's owner, or root can delete or rename files within that directory.

bash
# Set sticky bit
chmod +t /tmp
# Or using octal
chmod 1777 /tmp

The sticky bit appears as t in the others' execute position:

drwxrwxrwt 2 root root 4096 Oct 17 10:00 /tmp

This is commonly used on /tmp to prevent users from deleting each other's temporary files.

Combining Special Permissions

Special permissions add a fourth digit to octal notation:

bash
chmod 4755 file  # SUID + 755
chmod 2755 dir   # SGID + 755
chmod 1777 dir   # Sticky bit + 777
chmod 6755 file  # SUID + SGID + 755

The special permissions digit values:

  • 4 = SUID
  • 2 = SGID
  • 1 = Sticky bit

Changing Ownership (chown and chgrp)

To change who owns a file, use the chown command:

bash
# Change owner only
sudo chown marc file.txt

# Change owner and group
sudo chown marc:developers file.txt

# Change group only
sudo chown :developers file.txt
# Or use chgrp
sudo chgrp developers file.txt

# Recursive ownership change
sudo chown -R marc:developers /path/to/directory

Changing ownership typically requires root privileges (via sudo) unless you own the file and are changing it to a group you belong to.

Default Permissions and umask

When you create a new file or directory, Linux applies default permissions based on the umask value.

The umask is a mask that subtracts permissions from the base defaults:

  • Base default for files: 666 (rw-rw-rw-)
  • Base default for directories: 777 (rwxrwxrwx)

The umask value is subtracted from these base permissions.

bash
# View current umask
umask

# View in symbolic notation
umask -S

# Set umask
umask 0022

Common umask values:

0022 - Default on many systems

  • Files created with 644 (rw-r--r--): 666 - 022 = 644
  • Directories created with 755 (rwxr-xr-x): 777 - 022 = 755

0002 - Common for shared environments

  • Files created with 664 (rw-rw-r--): 666 - 002 = 664
  • Directories created with 775 (rwxrwxr-x): 777 - 002 = 775

0077 - Restrictive (private files)

  • Files created with 600 (rw-------): 666 - 077 = 600
  • Directories created with 700 (rwx------): 777 - 077 = 700

To make the umask permanent, add it to your shell's configuration file (~/.bashrc or ~/.zshrc).

Common Permission Scenarios

Making Scripts Executable

After creating a shell script, make it executable:

bash
chmod +x script.sh
# Now you can run it
./script.sh

Securing SSH Keys

SSH private keys must have restricted permissions:

bash
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh

SSH will refuse to use keys with overly permissive permissions.

Web Server Permissions

For web servers like Apache or Nginx:

bash
# Directories
chmod 755 /var/www/html

# Static files (HTML, CSS, JS)
chmod 644 /var/www/html/*.html

# PHP files (if not executing as owner)
chmod 644 /var/www/html/*.php

# Uploads directory (writable by web server)
chmod 775 /var/www/html/uploads

Shared Team Directories

For team collaboration:

bash
# Create shared directory with SGID
mkdir /shared/project
chmod 2775 /shared/project
chgrp developers /shared/project

Now all files created in /shared/project will belong to the developers group, and group members can modify them.

Troubleshooting Common Issues

"Permission denied" when running a script

Problem: bash: ./script.sh: Permission denied

Solution: Add execute permission:

bash
chmod +x script.sh

Can't delete a file you own

Problem: rm: cannot remove 'file.txt': Permission denied

Cause: You need write permission on the parent directory, not the file.

Solution:

bash
chmod +w /parent/directory

Or if the directory has the sticky bit set, you must be the file's owner or the directory's owner.

Can't access files in a readable directory

Problem: ls works but cat file fails

Cause: Directory lacks execute permission.

Solution:

bash
chmod +x /path/to/directory

SSH refuses to use your key

Problem: Permissions 0644 for '/home/marc/.ssh/id_rsa' are too open

Cause: SSH keys must be private (readable only by owner).

Solution:

bash
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh

Conclusion

Linux file permissions provide a robust and flexible security system:

  • Use ls -l to view permissions in symbolic format
  • Three permission types: read (r), write (w), execute (x)
  • Three permission groups: owner (u), group (g), others (o)
  • Permissions can be represented symbolically (rwxr-xr-x) or numerically (755)
  • Use chmod to change permissions, chown to change ownership
  • Special permissions (SUID, SGID, sticky bit) provide advanced control
  • Directories need execute permission to be accessible
  • The umask controls default permissions for new files

Best Practices

  • Follow the principle of least privilege (grant only necessary permissions)
  • Use 600 for private keys and sensitive files
  • Use 644 for regular files, 755 for executables and directories
  • Avoid 777 unless absolutely necessary
  • Use SGID for shared team directories
  • Regularly audit permissions on sensitive files

Understanding file permissions is essential for Linux system administration, security, and effective collaboration in multi-user environments.

References

  • chmod man page
  • chown man page
  • File system permissions - Wikipedia
Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Post navigation
What is Test-Driven Development (TDD)? A Practical IntroductionWhat is a Java Heap dump?
© 2007 - 2025 Marc Nuri