Understanding the Linux permission model — read, write, execute — for owner, group, and others, mastering octal and symbolic chmod, chown, umask, and the special bits SUID, SGID, and the sticky bit, through to securing SSH keys and shared directories in practice.

After episode 8 where we covered user & group management — how to create identities and group them — in this episode we'll discuss what those identities are allowed to do to files: file permissions & ownership.
Why is this topic important? Users and groups are only half of the Linux security model. The other half is the rules: who can read a config file containing credentials? Who can run a script? Who can write to a shared directory? Without understanding permissions, you'll be trapped between two extremes: too strict so applications break, or too loose (chmod 777 everywhere) so the server becomes an open door.
In this episode we'll cover: first, the basic permission model and the read/write/execute bits; second, octal vs symbolic chmod; third, chown and chgrp for ownership; fourth, umask as the default value; fifth, the special bits SUID, SGID, and the sticky bit; finally, a case study securing SSH key files and shared directories.
Every file in Linux has an owner, a group, and the others category. For each category, there are three permission bits:
| Bit | Value | Effect on Files | Effect on Directories |
|---|---|---|---|
r (read) | 4 | View file contents | List file names |
w (write) | 2 | Modify file contents | Create/delete/rename files inside |
x (execute) | 1 | Run the file | Enter (cd) the directory |
The octal values (4, 2, 1) aren't a coincidence — it's a binary system: combined bits sum to a single 0–7 digit. 7 = 4+2+1 (rwx), 6 = 4+2 (rw-), 5 = 4+1 (r-x), 4 = r--.
ls -l /etc/hosts-rw-r--r-- 1 root root 204 Agu 1 08:00 /etc/hostsLet's break down the output -rw-r--r--. The first character indicates the file type (- regular file, d directory, l symlink). The next nine characters are three triplets: rw- for the owner (root), r-- for the group (root), r-- for others. So /etc/hosts can be read by everyone, but only root can write.
statIf ls -l is the "summary", stat is the "full card" — showing permissions in both symbolic and numeric form, plus other metadata:
stat -c "%A %a %U:%G" /etc/hosts-rw-r--r-- 644 root:rootThe %A format shows the rwx string, %a shows the octal number (644), %U:%G shows owner:group. When you need to confirm "which owner does this 600 file belong to", stat -c "%a %U:%G" answers in one line — far easier to read than guessing from ls -l.
Note
Directories treat the bits differently — this is the biggest source of confusion. Read on a directory means you can see the list of file names; execute means you can enter the directory and access the files inside. Many new admins give r without x on a directory and wonder why its contents can't be accessed. For a browsable directory, you usually need r-x (5) or rwx (7). Remember: on a directory, x is "entry permission", not "execute".
chmod: Changing Permissionschmod changes the permission bits. There are two styles: octal (numbers) and symbolic (letters). Both produce the same result — choose whichever is easier to read in context.
chmod 755 skrip.sh
chmod 644 konfig.conf
chmod 600 rahasia.txtThe three octal digits are respectively for owner, group, others: 755 = rwxr-xr-x, 644 = rw-r--r--, 600 = rw-------. Note that the owner (you) must have write on a file to modify its contents later — that's why 600 is for files you write, 755 for executables others may run.
Caution
chmod 777 (rwx for everyone) is the instant solution most often reached for when an application "can't write", and it's also the most common entry point for hacking. Before falling back to 777, ask two questions: (1) who really needs access? — the answer is usually 755/644; (2) why does the application need to write? — maybe the process runs as the wrong user. 777 fixes the symptom, not the problem, while opening access to everyone on the system.
Symbolic mode works with u (user/owner), g (group), o (others), a (all), plus the operators +, -, =:
| Expression | Meaning |
|---|---|
u+x | Add execute for the owner |
g-w | Remove write for the group |
o= | Set others' permissions to empty |
a+r | Add read for all |
go-x | Remove execute for group and others |
chmod u+x skrip.sh
chmod g-w konfig.conf
chmod go= rahasia.txtThe diff below shows the command to make a script executable — before and after:
chmod +x deploy.sh
chmod u+x deploy.shchmod +x gives execute to all categories (a+x); chmod u+x restricts it to the owner only — a more conservative and commonly used choice.
chown and chgrp: Changing OwnershipPermissions only mean something if the ownership is correct. chown changes the owner and group; chgrp changes only the group:
sudo chown budi:webapps /var/www/proyek
sudo chown -R budi:webapps /var/www/proyek| Command | Effect |
|---|---|
chown budi file | Owner becomes budi, group unchanged |
chown budi:webapps file | Owner budi, group webapps |
chown -R | Applies recursively to the entire directory contents |
chgrp webapps file | Only the group changes |
umask: Setting Default PermissionsWhen you create a file, it isn't born with arbitrary permissions — the default value is set by umask. umask is a "mask" that subtracts permission bits from a base value:
umask
touch baru.txt
ls -l baru.txt0022
-rw-r--r-- 1 dev dev 0 Agu 2 09:00 baru.txtWith umask 0022, new files are born 644 (666 - 022 = rw-r--r--) and new directories 755 (777 - 022). The base logic: 666 for files (never executable by default), 777 for directories.
Tip
The umask value determines your default "leak". umask 0022 (standard) makes files readable by everyone; umask 0027 lets the group read but others not at all — a stricter choice for multi-user machines. umask 0077 makes everything completely private. For accounts that handle credentials, consider umask 0077. Make it permanent in ~/.bashrc: umask 0027.
Three special bits complete the basic permission model — each changes the behavior of executables or directories.
| Bit | Symbolic Notation | Effect |
|---|---|---|
| SUID (set user ID) | s on the owner bit | The file runs with its owner's rights, not the runner's |
| SGID (set group ID) | s on the group bit | Files run with the group's rights; directories pass the group on to new files |
| Sticky bit | t on the others bit | On directories: only the file's owner (or root) can delete |
The best-known SUID example is passwd — displayed as -rwsr-xr-x. This file is owned by root, but regular users are allowed to run it; thanks to SUID, the process runs with root rights so it can write to /etc/shadow. That's how users can change their own password without becoming root.
chmod 4755 alat-ku # SUID
chmod 2755 alat-ku # SGID
chmod 1777 /tmp # sticky bitThe sticky bit is the one you'll see most often — check /tmp:
drwxrwxrwt 1 root root 4096 Agu 2 09:00 /tmpThe t at the end marks the sticky bit as active: everyone can create files in /tmp, but only the file's owner (or root) can delete them — preventing user A from deleting user B's files in a shared directory.
Warning
SUID is a double-edged sword: a writable root-SUID file (for example a script a regular user can modify) is the most classic privilege escalation path in Linux. Never set SUID on shell scripts, and never copy SUID binaries around to "make access easier". Before setting SUID, ask: is there another way with minimal rights? The answer is almost always yes — usually with restricted sudoers (covered in the hardening episode).
Now let's apply all the concepts in two real scenarios.
chmod 600SSH refuses to use a private key with overly loose permissions — and this is deliberate, for security. When a new key is created, make sure its permissions are correct:
chmod 600 ~/.ssh/id_ed25519
ls -l ~/.ssh/id_ed25519600 means only the owner can read/write — the credential isn't readable by other users. If a key is accidentally created with 644, ssh will refuse with the message Permissions too open; chmod 600 is the cure.
The webapps group (from episode 8) wants to share a directory with these rules: all members can write, new files automatically get the webapps group, and only the owner can delete their own files. The command sequence:
sudo mkdir -p /srv/webapps
sudo chown root:webapps /srv/webapps
sudo chmod 2750 /srv/webappsBreaking down the three lines: chown root:webapps makes the owning group webapps; chmod 2750 means 2 (SGID) + rwxr-x--- — the group can enter and write, others can't at all; SGID ensures every new file inside automatically gets the webapps group, so all members can work with each other's files without waiting for an admin to change each file's group.
Tip
The rule of thumb guiding your permission decisions: the least privilege necessary (principle of least privilege). Config files only read by the application: 640 or 600. Scripts run by people: 755. Shared work directories: 2770 (SGID + group rwx). Public directories like /tmp: 1777. If a value feels "excessive", you're probably opening a door that doesn't need opening. Also check ownership: correct permissions on the wrong user are still insecure.
| Mistake | Symptom | Solution |
|---|---|---|
chmod 777 everywhere | All users can modify important files | Use groups + 770/2770; find the root cause |
| Execute bit on non-script files | Not dangerous but messy | Use 644/640 for data & configuration |
Forgetting x on directories | Files "not found" even though listable | Give r-x minimum to enter |
| SSH key too loose | Permissions too open | chmod 600 ~/.ssh/id_* |
chmod -R 777 on a directory containing credentials | Credentials readable by all users | Narrow the permissions, never use 777 |
Storing new keys/config without a suitable umask | Files born 644, readable by others | Tighten umask or chmod directly |
| Setting SUID on a script | Privilege escalation gap | Avoid it; use restricted sudoers |
In this episode 9, we've covered Linux's complete permission model: the read/write/execute bits for owner, group, and others; chmod in octal and symbolic styles; chown/chgrp for ownership; umask as the default value when files are born; the special bits SUID, SGID, and the sticky bit; and two real case studies — securing SSH keys and building a secure shared directory.
Key takeaways:
rwx triplet × 3 categories — and x means something different for files vs directories.755, 600) is concise; symbolic (u+x, g-w) is explicit — master both.777 fixes the symptom, not the problem — always seek the minimum permission.umask determines default permissions — 0027/0077 are far stricter than 0022.With this episode, your Linux administration foundation — basic commands, pipelines, text processing, backups, users/groups, and permissions — is complete. In the next episode 10, we'll shift to Package Management — getting to know apt, dnf, and the differences between distro ecosystems, understanding the repository concept, searching for and installing software, through to managing system updates safely. Stay motivated, because from here you start assembling a production-ready server!