chmod 644

rw-r--r--

chmod 644 sets the mode to rw-r--r--: the owner can read and write (4 + 2 = 6), and the group and everyone else can only read (4). It’s the default for new files under the common umask 022, and the right mode for most files that aren’t programs: HTML, CSS, images, source code, configuration without secrets.

What it allows

$ ls -l index.html
-rw-r--r-- 1 deploy deploy 5120 Oct 15 09:00 index.html

The owner can edit index.html; every user and service on the machine can read it; nobody can run it as a program. The mode doesn’t protect the file from deletion: removing or renaming it takes write and execute on the directory, not on the file.

644 is wrong for a directory. Without execute, nobody but root can enter it or open what’s inside, the owner included, and ls -l on it prints ? in place of each entry’s details. Directories get 755:

find /var/www/site -type f -exec chmod 644 {} +
find /var/www/site -type d -exec chmod 755 {} +
stat -c '%a %U:%G %n' /var/www/site/index.html   # 644 deploy:deploy /var/www/site/index.html

nginx and Apache serve a 644 file as long as every directory above it has execute for their user. When nginx logs (13: Permission denied) for a 644 file, run namei -l on its path to find the directory that lacks it.

How umask gives 644

Programs create files with 666, and the umask clears bits from it: 666 with 022 cleared is 644. It’s a mask, not a subtraction: umask 033 also gives 644, not 633.

When 644 is too open

Readable by everyone means readable by every local account and every compromised service. Keys, .env files and anything with a password want 600, or 640 with a service group. OpenSSH refuses a 644 private key with Permissions 0644 for '/home/alice/.ssh/id_ed25519' are too open. and ignores it.

Kubernetes shows it as 420

Secret and ConfigMap volumes default to defaultMode: 0644, and kubectl get pod -o yaml prints that as 420, its decimal value. YAML accepts either 0644 or 420; JSON only takes decimal. Don’t type the decimal into chmod: chmod 420 is r---w----.

In git and Docker

Git stores a non-executable file as 100644 and checks it out as 666 with your umask cleared, so a 600 file you commit comes back 644 on the next clone. Drop an executable bit with git update-index --chmod=-x file. Docker’s COPY keeps the mode from the build context; COPY --chmod=644 sets it explicitly.

Try it in the chmod Calculator

644 rw-r--r--

WhoReadWriteExecute
Owner
Group
Others
Special bits
Command
chmod 644 file

Runs in your browser. Nothing you enter is sent anywhere.