Skip to content
DevOps devops linux 6 min read

Understanding File Permissions

Every file and folder on a Linux server carries a small set of rules that decide who can read it, change it, or run it. These rules are called file permissions, and they are one of the most important security features in Linux. If you run a web server, a database, or any service on Ubuntu, getting permissions right is what stops one compromised account from reading or breaking everything else. This page teaches you how to read permissions confidently — the next page covers how to change them.

Why permissions matter

Linux is a multi-user system, meaning many people (and many programs) can use the same machine at the same time. On a real Ubuntu server you will have your own login, a root (administrator) account, and several service accounts — special non-human users like www-data (the user that runs the Nginx web server) or postgres (the user that runs the PostgreSQL database).

Permissions are the wall between all of them. They answer questions like: Can the web server read my SSL private key? Can a normal user delete the system logs? If you understand permissions, you can lock things down properly. If you ignore them, you leave doors open.

The three identities

Every permission is granted to one of three identities:

IdentityShort nameWho it is
UseruThe single owner of the file — usually the person or service that created it.
GroupgA named group of users. Everyone in the group shares this set of permissions.
OthersoEveryone else on the system — any user who is not the owner and not in the group.

A group is just a label that bundles users together. For example, you might add several developers to a developers group so they can all edit the same project folder without each needing to be the owner.

The three permission types

For each identity, Linux tracks three separate permissions, written as the letters r, w, x:

LetterNameOn a fileOn a directory (folder)
rreadView the file’s contents.List the names inside the folder.
wwriteChange or delete the file’s contents.Create, rename, or delete files inside.
xexecuteRun the file as a program or script.Enter the folder (use cd into it).

The meaning of x is the part beginners forget. On a file it means “this can be run.” On a directory it means “you are allowed to go into it.” A folder you can read but not execute lets you see file names but not actually open them.

Reading the permission string

The command ls -l (the -l means “long format”) shows permissions for every item in a folder. Try it on your home directory.

ls -l /var/www/html

Output:

total 12
-rw-r--r-- 1 www-data www-data  612 Jun 14 09:21 index.html
drwxr-xr-x 2 www-data www-data 4096 Jun 14 09:20 assets
-rwx------ 1 deploy   deploy    248 Jun 13 17:55 deploy.sh

Look at the first column, for example -rw-r--r--. It is 10 characters broken into four parts:

-   rw-   r--   r--
|   |     |     |
|   |     |     others (everyone else)
|   |     group
|   user (owner)
file type
  • Character 1 is the file type: - for a normal file, d for a directory, l for a symbolic link (a shortcut to another file).
  • Characters 2-4 are the user/owner permissions.
  • Characters 5-7 are the group permissions.
  • Characters 8-10 are the others permissions.

A letter means the permission is granted; a dash - means it is denied. So -rw-r--r-- reads as: it is a file; the owner can read and write; the group can read; others can read.

The two names after the number (www-data www-data) are the owner and the group. So index.html is owned by user www-data and group www-data.

Worked examples

StringTypeMeaning
-rw-r--r--fileOwner reads/writes; group and others read only. Typical for documents and web pages.
-rwxr-xr-xfileOwner has full control; group and others can read and run it. Typical for programs.
drwxr-xr-xdirectoryOwner full control; everyone can enter and list it. Typical for normal folders.
-rwx------fileOnly the owner can do anything. Everyone else is fully locked out. Use for secrets.
-rw-------fileOnly the owner reads and writes. Correct for an SSH key or password file.

Octal (numeric) notation

Typing rwx letters works, but Linux also lets you describe permissions with numbers. This is called octal notation (base-8), and you will see it everywhere — in documentation, scripts, and the chmod command.

The trick: each permission has a value, and you add them up for each identity.

PermissionValue
r (read)4
w (write)2
x (execute)1
- (none)0

You get one digit per identity, in order user, group, others. So:

  • rwx = 4 + 2 + 1 = 7
  • rw- = 4 + 2 + 0 = 6
  • r-x = 4 + 0 + 1 = 5
  • r-- = 4 + 0 + 0 = 4

Putting three digits together describes the whole file:

OctalStringCommon use
755rwxr-xr-xDirectories and executable scripts everyone may run.
644rw-r--r--Regular files like HTML, configs, images.
600rw-------Private files — SSH keys, .env secrets.
700rwx------Private folders or scripts only the owner uses.
775rwxrwxr-xShared team folder where a group can write.

Avoid 777 (rwxrwxrwx). It lets anyone read, change, and run the file. Tutorials suggest it as a quick “fix,” but on a server it is a serious security hole — it means a hacked web process can rewrite your files. Find the correct owner instead.

Checking permissions precisely

The stat command shows both the string and the octal number for any file, so you never have to convert by hand.

stat -c "%A %a %n" /var/www/html/index.html

Output:

-rw-r--r-- 644 /var/www/html/index.html

Here %A prints the rwx string, %a prints the octal number, and %n prints the file name.

When to use which

  • Use the rwx letter view (ls -l, stat -c %A) when you are reading and understanding permissions — it is easier for humans.
  • Use octal numbers (644, 755) when you are setting permissions in commands and scripts — it is precise and unambiguous.
  • Keep secrets at 600 and private folders at 700. Keep public web files at 644 and folders at 755. These four cover almost every real situation.

Best practices

  • Read before you write. Always run ls -l or stat to see current permissions before changing anything.
  • Give the least access needed. Start strict (600/700) and only open up if something actually needs it.
  • Never use 777 on a server. If a service can’t access a file, fix the owner, not by making it world-writable.
  • Protect secrets at 600. SSH keys, TLS private keys, and .env files must not be readable by group or others — most tools will even refuse to use a key that is too open.
  • Use groups for teams. Put collaborators in a shared group and use 775/664 rather than handing out ownership.
  • Remember x on directories. A folder needs execute permission to be entered, even if its files are readable.
Last updated June 15, 2026
Was this helpful?