Permissions and Ownership: Access Control

Permissions and Ownership: Access Control

POSIX permissions using rwx notation and octal notation. Differences between file and directory permissions. chown and chmod for changing ownership and permissions.

Every file and directory on Unix systems has an owner, a group, and permissions. These three pieces of information determine who may read, modify, or execute files. The concept dates back to the 1970s and protects multi-user systems against accidental changes and unauthorized access.

Permissions are divided into three categories: owner (user), group, and others. Each category can have three permissions: read, write, and execute. These nine bits define the access rights—Unix needs nothing more for functional access control.

Understanding the Permission System

The Three Permission Categories

$ ls -l /home/michael/documents/report.pdf
-rw-r--r-- 1 michael users 45632 Oct  6 14:23 report.pdf

The output begins with ten characters: -rw-r--r--. The first character (-) identifies the file type—a hyphen for regular files, d for directories. The remaining nine characters are divided into three groups of three:

  • rw- (characters 2–4): Owner permissions (michael)
  • r– (characters 5–7): Group permissions (users)
  • r– (characters 8–10): Permissions for all other users

The owner can read and write the file (rw-), the group can only read it (r--), and other users can also only read it (r--). Nobody except the owner can modify or delete the file.

Read, Write, Execute in Detail

Read (r) allows a file to be read. cat report.pdf works with the read permission; without it, you get “Permission denied.” For directories, r allows the contents to be listed with ls.

Write (w) allows a file to be modified. Editors can save changes, and data can be appended. Without the write permission, files are read-only—even the owner cannot save changes unless the permissions are changed first. For directories, w allows files to be created, deleted, and renamed.

Execute (x) makes files executable. Shell scripts and binaries require the execute permission to run. Without it, ./script.sh returns a permission error. For directories, x means permission to enter the directory—cd /path requires execute permission on /path.

Owner and Group

$ ls -l script.sh
-rwxr-xr-x 1 michael developers 2048 Oct  6 15:30 script.sh

The file belongs to user michael and group developers. Every user can belong to multiple groups. The id command displays your group memberships:

$ id michael
uid=1000(michael) gid=1000(michael) groups=1000(michael),27(sudo),1001(developers)

Michael is a member of the michael group (primary group), sudo (allowed to execute root commands), and developers. New files automatically receive the creator’s primary group. The newgrp command temporarily changes the primary group.

Groups make team collaboration possible without granting global permissions. All members of developers can read and execute script.sh, but only michael can modify it. Other users (not in the group) can also read and execute the script, but cannot modify it.

Changing Permissions with chmod

Symbolic Notation

The chmod command (change mode) changes permissions. Symbolic notation uses letters: u for user (owner), g for group, o for others, and a for all (all three categories).

$ chmod u+x script.sh

This adds (+) the execute permission (x) for the owner (u). The file becomes executable for the owner. Existing permissions remain unchanged.

$ chmod go-w file.txt

This removes (-) the write permission (w) from the group (g) and others (o). Only the owner can still write to the file. There is no u, so the owner’s permissions remain unchanged.

$ chmod a+r info.txt

This grants read permission (r) to everyone (a). The owner, group, and others can all read the file. Existing permissions remain intact; only the read permission is added.

Multiple changes can be combined:

$ chmod u+x,go-w script.sh

This makes the script executable for the owner and removes write permissions from the group and others. The comma separates the operations.

Octal Notation

Octal notation uses three digits from 0 to 7. Each digit encodes three bits (rwx) as a sum: r=4, w=2, x=1. The first digit applies to the owner, the second to the group, and the third to others.

$ chmod 755 script.sh

This sets the permissions to rwxr-xr-x:

  • 7 for the owner: r(4) + w(2) + x(1) = 7 = rwx
  • 5 for the group: r(4) + x(1) = 5 = r-x
  • 5 for others: r(4) + x(1) = 5 = r-x

The owner has full access, while the group and others can read and execute. This is the typical permission set for executable files that others should be able to use.

$ chmod 644 document.txt

This results in rw-r--r--:

  • 6 for the owner: r(4) + w(2) = 6 = rw-
  • 4 for the group: r(4) = 4 = r–
  • 4 for others: r(4) = 4 = r–

These are the standard permissions for text files—the owner can write, everyone else can only read. Documents, configuration files, and source code commonly use 644.

$ chmod 600 private.key

This sets rw-------:

  • 6 for the owner: r(4) + w(2) = 6 = rw-
  • 0 for the group: no permissions
  • 0 for others: no permissions

Only the owner has access. SSH keys require these permissions—SSH refuses authentication if private key files are too permissive.

Common Permission Patterns

Octal Symbolic Meaning Typical Use
755 rwxr-xr-x Owner has full access, others can read and execute Executable programs
644 rw-r–r– Owner can write, others can read Text files, configuration
600 rw——- Only the owner can read and write Private files, SSH keys
700 rwx—— Only the owner has full access Private scripts, personal directories
444 r–r–r– Everyone can read, nobody can write Read-only data
777 rwxrwxrwx Full access for everyone Insecure—never use

The 777 permission is a security risk. Any user can modify or delete the file. Temporary debugging situations may occasionally justify it—but never on production systems.

Directory Permissions

Execute Permission on Directories

For directories, the execute permission (x) has a special meaning: it allows users to enter the directory with cd. Without x, users cannot change into the directory, even if they have read permission.

$ ls -ld /home/michael/projects/
drwxr-xr-x 12 michael michael 4096 Oct  6 14:45 projects/

The leading d identifies a directory. The permissions rwxr-xr-x mean:

  • Owner: read, write, enter (rwx)
  • Group: read, enter (r-x)
  • Others: read, enter (r-x)

Everyone can execute cd /home/michael/projects/ and list the contents with ls. Only the owner can create, delete, or rename files.

Read Without Execute

$ chmod 744 directory/

This sets rwxr--r-- on a directory. The group and others have only r (read), not x (execute). They cannot run cd directory/, even though they theoretically have permission to list the contents. Without x, the directory cannot be entered—ls fails with “Permission denied.”

This combination is rarely useful. Directories generally need r and x together (r-x); otherwise, the read permission is effectively useless.

Write Permission on Directories

The write permission (w) on directories allows files to be created, deleted, and renamed within the directory. It applies independently of the permissions on the files themselves.

$ ls -ld project/
drwxrwxr-x 5 michael developers 4096 Oct  6 15:12 project/

$ ls -l project/important.txt
-r--r--r-- 1 sandra developers 1024 Oct  3 10:22 important.txt

The project/ directory has rwxrwxr-x—the owner and the group can write. The file important.txt is read-only (r--r--r--) and belongs to sandra.

Michael can still delete important.txt because he has write permission on the parent directory. File permissions protect only the file’s contents, not the file’s existence. The directory permission determines whether a file can be deleted.

Typical Directory Permissions

Octal Symbolic Meaning Typical Use
755 rwxr-xr-x Owner can write, others can navigate Standard user directories
775 rwxrwxr-x Owner and group can write Team projects
700 rwx—— Only the owner has access Private directories
1777 rwxrwxrwt Everyone can write, only owners can delete /tmp with the Sticky Bit

The Sticky Bit (the leading 1 in octal notation) on directories allows everyone to create files, but only the owner of a file (or the owner of the directory) can delete it. /tmp uses this behavior—everyone can create temporary files, but nobody can delete another user’s files.

Changing Ownership with chown

Changing User and Group

The chown command (change owner) changes the owner of a file. Only root can use chown—ordinary users cannot transfer files to other users. This prevents users from bypassing quota systems (disk space limits per user).

$ sudo chown sandra document.txt

The file now belongs to sandra. The group remains unchanged. Sandra can now change the permissions and act as the owner.

$ sudo chown sandra:developers document.txt

This changes the owner to sandra and the group to developers. The colon separates the user and the group. Both are changed with a single command.

$ sudo chown :admins file.txt

Only the group is changed (to admins); the owner remains the same. A colon without a user name changes only the group.

Recursive Changes

The -R (recursive) option changes ownership for entire directory trees:

$ sudo chown -R michael:developers /opt/project/

All files and subdirectories in /opt/project/ now belong to michael with the group developers. This is useful after extracting archives or transferring ownership of project directories.

$ sudo chmod -R 755 /opt/project/bin/

All files in /opt/project/bin/ and its subdirectories receive permission 755. Scripts and programs become executable. Recursive changes save time compared to running chmod on every file individually.

Caution: Recursive chmod can cause serious damage. Running chmod -R 777 / as root would make the entire system writable by everyone—a catastrophic failure for both stability and security. Always verify recursive commands before executing them.

Special Permission Bits

SetUID — Execute as the Owner

The SetUID (Set User ID) bit allows a program to run with the permissions of its owner instead of the user who starts it. This is powerful and potentially dangerous.

$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Mai 28  2024 /usr/bin/passwd

The s in rws indicates SetUID. The passwd program is owned by root. Ordinary users can execute it, and it runs with root privileges. This is necessary because passwd must modify the /etc/shadow file, which only root may access.

Without SetUID, ordinary users could never change their passwords because /etc/shadow is strictly protected. With SetUID, passwd temporarily runs as root, updates the file, and exits. The user never receives root privileges—only the program does.

For security reasons, SetUID works only with executable files, not shell scripts. A SetUID script could be manipulated through environment variables and is therefore considered too dangerous.

$ chmod u+s programm
$ chmod 4755 programm

Both commands set the SetUID bit. Symbolic notation uses u+s; octal notation uses a leading 4 (4755 instead of 755). The s then appears in the owner’s execute field in ls -l.

SetGID — Execute as the Group

The SetGID (Set Group ID) bit works similarly to SetUID, but for groups. Programs run with the permissions of the file’s group instead of the executing user’s group.

$ chmod g+s programm
$ chmod 2755 programm

Octal notation uses a leading 2 (2755). The s appears in the group’s execute field in ls -l.

On directories, SetGID has a different meaning: new files automatically inherit the directory’s group instead of the creator’s primary group. This is useful for team directories.

$ ls -ld /opt/team-project/
drwxrwsr-x 8 michael developers 4096 Oct  6 16:20 team-project/

The s in the group field (rws) indicates SetGID. Every file created in this directory automatically belongs to the developers group, regardless of who created it. This simplifies team collaboration because all group members receive the same group permissions on new files.

Sticky Bit — Only the Owner Can Delete

The Sticky Bit on directories prevents users from deleting files that belong to other users, even if they have write permission on the directory. Only the owner of a file (or the owner of the directory, or root) may delete it.

$ ls -ld /tmp/
drwxrwxrwt 15 root root 4096 Oct  6 16:45 /tmp/

The t at the end (rwt instead of rwx) indicates the Sticky Bit. The /tmp directory has permission 1777—everyone can create files, but nobody can delete another user’s files. User A may read a file belonging to user B (if the file permissions allow it), but cannot delete it.

$ chmod +t directory/
$ chmod 1777 directory/

Symbolic notation uses +t; octal notation uses a leading 1 (1777). The Sticky Bit is useful for shared directories such as /tmp, where all users store temporary files.

Combined Special Permission Bits

The special permission bits can be combined:

Octal Meaning
4755 SetUID, normal permissions rwxr-xr-x
2755 SetGID, normal permissions rwxr-xr-x
1777 Sticky Bit, full permissions rwxrwxrwx
6755 SetUID + SetGID
7755 All three special permission bits

The first octal digit encodes the special permission bits: 4=SetUID, 2=SetGID, 1=Sticky Bit. Adding them combines the bits: 4+2=6 for SetUID+SetGID, 4+2+1=7 for all three.

Practical Applications

Secure Script Access

A script backup.sh should create backups, but only the administrator should be able to modify it:

$ sudo chown root:admins backup.sh
$ chmod 750 backup.sh

This results in rwxr-x---: root has full access, the admins group can execute the script (start backups), and ordinary users have no access. The script itself is protected against modification.

Team Project Directory

A project directory for a development team:

$ sudo mkdir /opt/project
$ sudo chown michael:developers /opt/project
$ sudo chmod 2775 /opt/project

This sets rwxrwsr-x with SetGID. All team members (group developers) can create, modify, and delete files. New files automatically belong to the developers group. Other users can view the contents (r-x), but cannot modify them.

Private Home Directories

User home directories should be private:

$ chmod 750 /home/michael

This sets rwxr-x---: Michael has full control, members of his group can enter and read the directory (useful for shared files), and other users have no access. By default, home directories are often 755, allowing everyone to read them. 750 is more secure.

Web Server Directories

A web server needs read access to HTML files, but not write access:

$ sudo chown www-data:www-data /var/www/html
$ sudo chmod 755 /var/www/html
$ find /var/www/html -type f -exec chmod 644 {} \;
$ find /var/www/html -type d -exec chmod 755 {} \;

Directories receive 755 (traversable), files receive 644 (readable). The web server process (running as www-data) can read everything but cannot modify anything. Upload directories require 755 or 775 if write access is needed.

Umask and Default Permissions

Understanding umask

The umask (user file creation mask) defines which permissions are automatically removed from newly created files and directories. It is applied by subtracting permissions from the maximum defaults.

$ umask
0022

The default umask is usually 022. New files theoretically start with 666 (rw-rw-rw-), and new directories with 777 (rwxrwxrwx). The umask is subtracted:

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

A umask of 077 removes all permissions for the group and others:

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

All newly created files are then private. This is more secure, but less practical for team collaboration.

$ umask 002

This temporarily sets the umask to 002. New files receive 664 (rw-rw-r--), and directories receive 775 (rwxrwxr-x). The group can write—useful for team directories. The change applies only to the current shell session. Permanent changes belong in ~/.bashrc or /etc/profile.

Checking Default Permissions

$ touch testfile
$ mkdir testdirectory
$ ls -ld testfile testdirectory
-rw-r--r-- 1 michael michael    0 Oct  6 17:15 testfile
drwxr-xr-x 2 michael michael 4096 Oct  6 17:15 testdirectory/

New files receive 644, and new directories receive 755, matching the default umask of 022. This provides a balance between accessibility and protection—the owner can write, while others can only read.

Debugging Permissions

Checking Access

The ls -l command displays permissions, but sometimes this is not enough to understand a “Permission denied” error. The namei command displays the complete path along with the permissions of every component:

$ namei -l /home/michael/projects/website/index.html
f: /home/michael/projects/website/index.html
drwxr-xr-x root    root    /
drwxr-xr-x root    root    home
drwxr-x--- michael michael michael
drwxr-xr-x michael michael projects
drwxr-xr-x michael michael website
-rw-r--r-- michael michael index.html

Accessing index.html requires execute permission on every directory in the path. The /home/michael directory has drwxr-x---—only the owner and the group may enter it. Other users fail at cd /home/michael and therefore never reach index.html, even if the file itself is readable.

Checking Effective Permissions

The getfacl command displays extended ACLs (Access Control Lists), if they are present:

$ getfacl file.txt
# file: file.txt
# owner: michael
# group: developers
user::rw-
group::r--
other::r--

ACLs allow more fine-grained permissions than the standard rwx model—individual users or additional groups can receive specific permissions. Most systems rarely use ACLs because rwx permissions are sufficient for almost all situations.

Security Considerations

Never Use 777

The permission 777 (rwxrwxrwx) is almost always the wrong choice. Anyone can read, modify, or delete the file. A malicious user could inject malware, steal data, or compromise the system.

Debugging situations sometimes tempt administrators to run chmod 777 because “it finally works.” This is dangerous. The correct solution is to determine the proper permissions—not to assign the most permissive ones. A web upload directory may require 775, but never 777.

Use SetUID Carefully

SetUID programs run with elevated privileges. Bugs or security vulnerabilities in SetUID root programs are critical because they can allow privilege escalation. Every additional SetUID program increases the system’s attack surface.

Only trusted, well-maintained programs should use SetUID. Never set SetUID on your own scripts—they are too prone to errors. Use sudo with specific rules instead.

Regular Audits

$ find / -perm -4000 -ls 2>/dev/null

This finds every SetUID file on the system. An unknown SetUID file is suspicious—it may indicate a compromised system or incorrectly configured software.

$ find /var/www -type f -perm -002 -ls

This finds all files under /var/www that are world-writable (-002). Web server files should never be world-writable—they represent a security risk.

Summary

Unix permissions using rwx for User, Group, and Others are simple but effective. Octal notation (644, 755, 600) is compact and quick to read. SetUID, SetGID, and the Sticky Bit extend the permission model for special requirements.

Regular files typically use 644 (owner writes, others read). Executable programs use 755 (owner writes, everyone executes). Private data uses 600 (owner only). Directories typically use 755 or 700. These four permission patterns cover roughly 90% of all situations.

The next article covers links between files—hard links and symbolic links—and explains the inode concept that underlies permissions and file names.


Software and Versions Used

This discussion refers to:

  • POSIX permissions: Standard since Unix Version 7 (1979)
  • Operating systems: All Linux distributions and BSD systems
  • Context: Universal across all Unix-like systems
  • As of: October 2025

Next steps:

Michael of the Dragons

develops books, software, and open frameworks around technical systems, digital independence, and durable software architectures.
More about Michael →
Permissions and Ownership: Access Control
← Next Article Links and File Types: Flexible Usage
Permissions and Ownership: Access Control
Previous Article → Filesystem Hierarchy: The Directory Tree