Skip to content
Home
Linux File Permissions: Understanding chmod, chown, and umask

Linux File Permissions: Understanding chmod, chown, and umask

Linux Linux 7 min read 1469 words Beginner ExcellentWiki Editorial Team

File permissions are the foundation of Linux security. Every file and directory has an owner, a group, and a set of permissions that determine who can read, write, and execute it. Understanding permissions is essential for system administration and application deployment.

Permission Model

File Types

ls -la
-rw-r--r--  1 alice devops  1024 Jun 27 10:00 file.txt
^
└── File type: - (file), d (directory), l (symlink), b (block), c (character)

Permission Groups

-rw-r--r--
 │││││││
 ││││││└── Others: read (r--)
 │││││└─── Others: ---
 ││││└──── Group: read (r--)
 │││└───── Group: ---
 ││└────── Owner: write (w-)
 │└─────── Owner: read (r-)
 └──────── Owner: ---

Owner, group, and others each can have three permissions:

  • r (4) — read
  • w (2) — write
  • x (1) — execute

chmod: Changing Permissions

Symbolic Mode

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

# Remove write for group
chmod g-w file.txt

# Add read for others
chmod o+r file.txt

# Set exact permissions for all
chmod a=rwx file.sh

# Multiple changes
chmod u+x,g-w,o+r file

# All + execute
chmod +x script.sh         # same as a+x

# Recursive — add execute to directories only
find /path -type d -exec chmod 755 {} \;
find /path -type f -exec chmod 644 {} \;

Numeric (Octal) Mode

# 755 = rwxr-xr-x
chmod 755 script.sh    # Owner: rwx, Group: r-x, Others: r-x

# 644 = rw-r--r--
chmod 644 file.txt     # Owner: rw-, Group: r--, Others: r--

# 600 = rw-------
chmod 600 private.key  # Owner only (SSH keys, secrets)

# 700 = rwx------
chmod 700 private_dir  # Owner full access only

# 444 = r--r--r--
chmod 444 readonly.txt

# 000 = --------- (no one can access)
chmod 000 secret.txt   # Use carefully!
OctalBinaryPermissions
7111rwx
6110rw-
5101r-x
4100r–
3011-wx
2010-w-
1001–x
0000

Common Permission Sets by Use Case

# Personal files
chmod 600 private.key          # Owner read/write only
chmod 700 ~/.ssh               # Owner full access to SSH config
chmod 600 ~/.ssh/id_rsa        # Private SSH key

# Web server files
chmod 644 index.html           # Everyone reads, owner writes
chmod 755 uploads/             # Everyone can enter, owner writes

# Shared project files
chmod 664 shared_file.txt      # Owner+group rw, others read
chmod 775 shared_dir/          # Owner+group full, others read/enter

# Scripts and executables
chmod 755 deploy.sh            # Executable by all
chmod 755 /usr/local/bin/*     # System-wide executables

chown: Changing Ownership

# Change owner
sudo chown alice file.txt

# Change group
sudo chown :devops file.txt

# Change both
sudo chown alice:devops file.txt

# Change group only (short form)
sudo chown .devops file.txt    # some systems

# Recursive (entire directory tree)
sudo chown -R alice:devops /opt/myapp/

# Preserve root ownership for system files
# Never chown system binaries or directories

When to Use chown

  • Web application directories (owner = www-data or application user)
  • User home directories
  • Project directories after moving files between users
  • Mount points for removable media

umask: Default Permissions

The umask sets default permissions for newly created files and directories. It subtracts from the base permissions (666 for files, 777 for directories).

# View current umask
umask
# 0022

# Calculate effective permissions:
# File: 666 - 022 = 644 (rw-r--r--)
# Dir:  777 - 022 = 755 (rwxr-xr-x)

# Set umask for current session
umask 0027

# Common umask values:
# 0022 — Files: 644, Dirs: 755 (default, secure for shared)
# 0002 — Files: 664, Dirs: 775 (collaborative groups)
# 0077 — Files: 600, Dirs: 700 (private)
# 0000 — Files: 666, Dirs: 777 (insecure — all can write)

# Set permanently in ~/.bashrc
echo "umask 0027" >> ~/.bashrc

Special Permissions

SUID (Set User ID) — 4xxx

When set on an executable, the program runs with the file owner’s privileges:

# Find SUID files (potential security risk)
find / -perm -4000 -type f

# Set SUID
chmod u+s /usr/bin/myapp
chmod 4755 /usr/bin/myapp      # rwsr-xr-x

# Remove SUID
chmod u-s /usr/bin/myapp

SGID (Set Group ID) — 2xxx

When set on a file, the program runs with the group’s privileges. When set on a directory, new files inherit the directory’s group:

# Set SGID on directory (new files inherit group)
chmod g+s /shared/project
chmod 2755 /shared/project    # rwxr-sr-x

# Find SGID files
find / -perm -2000 -type f

# Remove SGID
chmod g-s /shared/project

Sticky Bit — 1xxx

On directories, only file owners can delete their own files (used on /tmp):

# Set sticky bit
chmod +t /shared/temp
chmod 1777 /shared/temp       # rwxrwxrwt

# Find sticky bit directories
find / -perm -1000 -type d

# Remove sticky bit
chmod -t /shared/temp

ACLs (Access Control Lists)

For more granular permissions than the standard rwx model:

# Install ACL utilities
sudo apt install acl    # Debian/Ubuntu
sudo yum install acl    # RHEL/CentOS

# Set ACL — give specific user access
setfacl -m u:bob:rwx /shared/project

# Set ACL — give specific group access
setfacl -m g:developers:rx /shared/project

# Remove ACL entry
setfacl -x u:bob /shared/project

# View ACLs
getfacl /shared/project

# Copy ACLs from one file to another
getfacl file1 | setfacl --set-file=- file2

# Set default ACL for new files in directory
setfacl -dm u:bob:rwx /shared/project

# Recursive (apply to existing files)
setfacl -R -m u:bob:rx /shared/project

Checking ACL Support

# Check filesystem was mounted with acl
mount | grep "acl"
tune2fs -l /dev/sda1 | grep "Default mount options"

# Most modern Linux filesystems have ACL enabled by default

Real-World Implementation Tips

Production Considerations

When moving from development to production, several factors become critical. Error handling should be comprehensive — every external call (database, API, file system) should have proper error checking, logging, and retry logic where appropriate. Performance monitoring through metrics and structured logging helps identify bottlenecks before they affect users.

Testing Strategy

A thorough testing approach combines multiple levels:

  • Unit tests verify individual functions and methods in isolation
  • Integration tests validate that components work together correctly
  • Edge case tests cover boundary conditions, empty inputs, and error states
  • Performance tests ensure the system meets latency and throughput requirements

Test data should be realistic but controlled. Mock external dependencies to make tests fast and deterministic. Aim for tests that are independent, repeatable, and fast enough to run on every commit.

Documentation

Good documentation is essential for maintainable code. Follow these principles:

  • Document the “why” not just the “what” — explain design decisions
  • Keep examples up to date with the code
  • Include usage examples for public APIs
  • Document configuration options and their defaults
  • Explain error conditions and recovery strategies

Security Best Practices

Security should be considered throughout development:

  • Validate all inputs at system boundaries
  • Use parameterized queries for database access
  • Store secrets in environment variables or secret managers
  • Keep dependencies updated to patch vulnerabilities
  • Apply the principle of least privilege

Performance Optimization

Optimize based on measured data, not assumptions:

  1. Profile before optimizing — identify actual bottlenecks
  2. Measure the impact of each change
  3. Consider the trade-off between speed and readability
  4. Cache expensive operations with appropriate invalidation
  5. Use connection pooling for database and network resources

Monitoring and Observability

Production systems need visibility:

  • Structured logging with correlation IDs for request tracking
  • Metrics for latency, throughput, error rates, and resource usage
  • Health check endpoints for load balancers and orchestration
  • Distributed tracing for request flows across services
  • Alerts for anomaly detection based on baselines

These patterns apply across all programming languages and frameworks. The specific implementation varies, but the principles remain consistent.

FAQ

Q: What is the difference between chmod 755 and chmod u=rwx,g=rx,o=rx? A: They produce the same result. Numeric and symbolic modes are interchangeable. Numeric is shorter for common patterns; symbolic is more readable for complex changes.

Q: Why would I use 775 vs 755? A: 775 gives the group write access (for collaborative projects). 755 restricts write to the owner only.

Q: How do I prevent other users from accessing my files? A: Use chmod 700 ~/private for directories and chmod 600 file for files. Set umask 0077 for new files.

Q: What permissions should web server files have? A: Files: 644 (owner write, everyone read). Directories: 755 (owner write, everyone enter). Owner should be your user, group www-data if Apache/Nginx needs to write.

Q: How do I recursively change permissions? A: chmod -R 755 directory/ changes everything. Better: find . -type d -exec chmod 755 {} \; and find . -type f -exec chmod 644 {} \;.

Q: What is the sticky bit used for? A: The sticky bit (chmod +t) on /tmp ensures users can only delete their own files, even though everyone has write permission.

Q: Are ACLs better than standard permissions? A: ACLs provide more granular control (per-user access, complex rules). Standard permissions are simpler and sufficient for most cases. Use ACLs when you need fine-grained multi-user access.

For a comprehensive overview, read our article on Bash Scripting Basics.

For a comprehensive overview, read our article on Cron Jobs Guide.

Section: Linux 1469 words 7 min read Beginner 756 articles in section Report inaccuracy Back to top