POSIX Permission Bits 📖
If I ask, what does chmod 777 do - you might say it gives everyone full permissions over that file. What about chmod 0777 or chmod 660? If you need an explainer, then make sure to read along as we’ll be covering, from start to end, how POSIX-compliant permission bits work, a common permission system used on UNIX-like OS’s like macOS, BSD and of course … Linux!
A breif introduction to binary numbers
Hopefully, you’re already familliar with binary numbers, but if you’re not heres a quick rundown:
- We humans use base-10 (denary or decimal) for counting so each place value increments in powers of 10 like this: 1, 10, 100, 1000, etc.
- Computers use base-2 (or binary) for counting so each place value increments in powers of 2 like this: 1, 2, 4, 8, 16, etc.
| Base-2 & Base-10 |
|---|
| In base-2, the maximum amount of digits is 2 (0-1 inclusive). |
| In base-10, the maximum amount of digits is 10 (0-9 inclusive). |
To write 255 in base-10, we do the following:
| 10² = 100 | 10¹ = 10 | 10⁰ = 1 |
|---|---|---|
| 2 | 5 | 5 |
So that means 2 * 100 + 5 * 10 + 5 * 1 = 255. In this case we have 3 digits which are used to represent the number.
To do the same in base-2, we do the following:
| 2⁷ = 128 | 2⁶ = 64 | 2⁵ = 32 | 2⁴ = 16 | 2³ = 8 | 2² = 4 | 2¹ = 2 | 2⁰ = 1 |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
So that means 128 * 1 + 64 * 1 + 32 * 1 + 16 * 1 + 8 * 1 + 4 * 1 + 2 * 1 + 1 * 1 = 255. In this case we have 8 bits (binary digits) which are used to represent the number.
If we wanted to do a different number, say 192, the binary value would be:
| 2⁷ = 128 | 2⁶ = 64 | 2⁵ = 32 | 2⁴ = 16 | 2³ = 8 | 2² = 4 | 2¹ = 2 | 2⁰ = 1 |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
As 128 + 64 = 192 (we don’t add the value if it’s set to zero).
Symbolic file permissions
When you run the ls -l command, you will see something like -rwxrwxrwx for the permissions of an object in your file system. This is the symbolic representation of the permissions. Let’s break it down:
- The first
-is a placeholder which usually exists on normal files. In place of this you might see different letters which identify a type of object on the filesystem. Below is a list of the common “special file” designators:dis a directory (folder)cis a character devicelis a symbolic linkpis a named pipesis a socketbis a block deviceDis a door
- The next 3 characters, in our example is
rwx, but could berw-,r--, or any combination are the permission bits for the owner. In our case,read,write, andexecutepermissions have been granted. - The next 3 characters, are the permission bits for the owner’s group.
- The last 3 characters, are the permission bits for everyone else.
To set permissions for an object on the filesystem using the symbolic method, one can use the chmod command. You can use + to set a bit, and - to unset a bit. To make a file executable for the owner you can use this command:
chmod +x <file>
Note, on the third letter of each grouping, you may see another letter othan than
x. You may seesortif setuid/setgid or sticky bits are set and the file is executable or you may seeSorTif they are set and the file is not executable. This can be confusing to understand which is why the next section will explain the numerical form. (This is explained further down.)
Numerical file permissions
So, leading up from the previous section - how can we express -rwxrwxrwx as a number. Well, we first need to interpret the permission bits in binary first. Now, you could go two possible ways about this (and one of them is wrong).
Option 1 - Just use one binary number code for the entire permission
| R | W | X | R | W | X | R | W | X |
|---|---|---|---|---|---|---|---|---|
| 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
In this way, the core permissions (read, write and execute or RWX) for the owner, group and everyone else are layed out in sequence and each permission has its own value which adds to the final sum. The sum of this 9-bit value is 511. Which is difficult to interpret for both us and the computer. So, clearly this is the incorrect way of doing it.
Option 2 - Split the permission into the 3 components (owner, group and everyone else) and use 3-bits per component
| R | W | X | R | W | X | R | W | X |
|---|---|---|---|---|---|---|---|---|
| 4 | 2 | 1 | 4 | 2 | 1 | 4 | 2 | 1 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
The sum of each 3-bit number is 7 (4 + 2 + 1), which gives us a permission code of 777. This is the correct numerical representation of the permission bits. This way makes it easier to understand when converted into denary as the first digit represents permission codes for the owner (0-7), then the next one is for the group (0-7) and the last one is for everyone else (also 0-7).
| Denary value | Binary value | Symbolic notation | Meaning |
|---|---|---|---|
| 0 | 000 | --- | No permissions |
| 1 | 001 | --x | Execute only |
| 2 | 010 | -w- | Write only |
| 3 | 011 | -wx | Write & execute only |
| 4 | 100 | r-- | Read only |
| 5 | 101 | r-x | Read & execute only |
| 6 | 110 | rw- | Read & write only |
| 7 | 111 | rwx | Read & write & execute (full permissions) |
Given that now we know how to express the permissions for -rwxrwxrwx is both symbolic and numerical form, how can we manipulate it now? Simple, just change one of the bits. Say you want to deny write access to everyone else but yourself and your user group. Just change the W bit from 1 to a 0 in the last group.
So 111 111 111 becomes 111 111 101 which is equal to rwx rwx r-x which is also equal to 775 (as 4 + 1 = 5).

Now I mentioned before about how the x can sometimes be an s,t or the uppercase variants depending on the other special bits. This is where we can introduce the 4th optional octet. It is placed at the beginning of the permission code. The default value is 0 which means none of them are set. This means that:
- Permission
777is the same as0777 - Permission
775is the same as0775
Example for 0775:

Here’s a little explainer of the special bits:
- The user bit known as SUID, causes the file to be executed as the owner no matter who passed the command. The most common example of this is
sudo. Thesudobinary must have the SUID bit set because it must run as root (the owner) in order to elevate the command your account is trying to run. - The group bit known as SGID, causes the file to be executed as the owner’s group no matter who passed the command, similar to SUID.
- The final bit is called the sticky bit, this has no effect on files but when applied to a directory, it prevents deletion of the folder and files making it such that only the owner and root can remove the files.
The SUID symbolic letters
sandSwill only appear in the first grouping in place of thex. For SGID, the same letters (s&S) will be used but this time, in the second grouping. The sticky bit,torT, appears in the third group in place of thex.
So, if we wanted to create a file that meets these requirements and the owner is root:
- SUID bit is set (file always runs as root)
- SGID bit is not set (not needed)
- Sticky bit is not set
- Can only be modified by the owner, not the group or anyone else.
- Can be executed by everyone.
We can set the bits accordingly:

In the symbolic form:
-rwsr-xr-x
And in the numeric form:
4755
We can apply this to a file using chmod now:
chmod 4755 file
We can also use the symbolic method, but that could take several commands to adjust each aspect of the permissions (user, group and everyone) so for these cases, the numerical method is preferred.
And that’s that! You now know how to master permissions on your POSIX filesystem!
Comments could not load. This is often caused by a privacy extension or strict tracking protection blocking GitHub. Try allowlisting this site or opening the page in another browser.