Skip to content
Go back

The umask You've Been Ignoring

By SumGuy 4 min read
The umask You've Been Ignoring

You create a file. Its permissions are 644. You create a directory. It’s 755. Where do these numbers come from?

Not chmod. Not the filesystem. Your umask. And most people don’t even know it exists.

Umask controls what permissions get removed from files you create. It’s a permission mask. Boring name. Critical for shared systems.

What Is umask?

Umask is a number—default is often 0022—that gets subtracted from the default permissions when you create a file or directory.

Default file permissions: 666 (read+write for all) Default directory permissions: 777 (read+write+execute for all)

With umask 0022:

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

That’s where 644 and 755 come from. Not magic. Math.

How to Calculate

Umask works on octal digits. Each digit is a permission class:

022 = [owner] [group] [other]
0 0 2

So other gets: 7 (all) - 2 (write) = 5 (read + execute)

Breakdown: 022 vs 027

0022 (common on shared systems):

Files: 666 - 022 = 644 (user rw, group r, other r)
Directories: 777 - 022 = 755 (user rwx, group rx, other rx)

0027 (more restrictive):

Files: 666 - 027 = 640 (user rw, group r, other nothing)
Directories: 777 - 027 = 750 (user rwx, group rx, other nothing)

Use 027 if you want others to have zero access to your files.

0077 (paranoid):

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

Check Your umask

Terminal window
$ umask
0022

See? It’s set. You probably never touched it.

Set Umask Temporarily

Terminal window
# Make it restrictive
$ umask 0077
$ touch testfile
$ ls -l testfile
-rw------- 1 user user 0 Mar 7 10:00 testfile
only user can read/write

Back to normal:

Terminal window
$ umask 0022
$ touch testfile2
$ ls -l testfile2
-rw-r--r-- 1 user user 0 Mar 7 10:00 testfile2

Set Umask Permanently

Add to your shell config:

~/.bashrc or ~/.zshrc
umask 0027

System-wide (affects all users):

/etc/profile or /etc/profile.d/umask.sh
umask 0022

For SSH logins (specific to OpenSSH):

/etc/ssh/sshd_config
# Add this line
Umask 0022

When Umask Matters

Shared system: Multiple users need to access each other’s files.

Terminal window
# Bad: user1 creates a file, user2 can't read it
$ umask 0077
$ echo "secret" > shared.txt
$ ls -l shared.txt
-rw------- 1 user1 user1 7 Mar 7 10:00 shared.txt
# user2 tries to read
$ cat /home/user1/shared.txt
Permission denied

Fix:

Terminal window
$ umask 0022
$ echo "secret" > shared.txt
$ ls -l shared.txt
-rw-r--r-- 1 user1 user1 7 Mar 7 10:00 shared.txt
# user2 can read it
$ cat /home/user1/shared.txt
secret

Shared directories:

Terminal window
# Create a project directory
$ mkdir -p /shared/project
$ chmod 770 /shared/project
$ chgrp developers /shared/project
# Now both owner and group (developers) can write
$ ls -ld /shared/project
drwxrwx--- 2 user developers 4096 Mar 7 10:00 /shared/project

But if your umask is 0077, files created inside won’t be group-writable:

Terminal window
$ umask 0077
$ touch /shared/project/file.txt
$ ls -l /shared/project/file.txt
-rw------- 1 user developers 0 Mar 7 10:00 file.txt
group can't write!

Fix it per-directory:

Terminal window
# For files created in this dir: remove group-write restriction
$ setfacl -d -m g:developers:rwx /shared/project
# Or just remind users to umask before working here
$ (umask 0002; touch file.txt)
$ ls -l file.txt
-rw-rw---- 1 user developers 0 Mar 7 10:00 file.txt
group can write

Docker / Containers

Container images bake in umask. If your Dockerfile needs specific permissions:

FROM ubuntu
RUN umask 0022 && apt-get update
RUN touch /app/config && chmod 644 /app/config

Or set it in the entrypoint:

entrypoint.sh
#!/bin/bash
umask 0022
exec "$@"

Gotchas

umask doesn’t add permissions. If you touch a_file with umask 0077, it gets 600 (rw only). You can’t then expect umask to give you 755 for a directory—it removes, it doesn’t add.

Existing files aren’t affected. Changing umask only affects newly created files. Old files keep their permissions.

Some apps ignore umask. Web servers, databases, etc. often set their own permissions via chmod in code.

Best Practice

That’s it. Simple math. But the security implications are real.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it may appear here.


Previous Post
Multi-Platform Docker Builds with buildx
Next Post
Docker Network Aliases: The Feature Nobody Uses

Related Posts