How to Use umask Command in Linux: Control Default File Permissions

Robert Johnson

Ever created a script in Linux, only to realize it’s world-readable when it contains sensitive credentials? Or worse—discovered that your automated backup files have been exposed to every user on the system?

That’s where umask comes in. This little command is your first line of defense against permission nightmares.

In this guide, I’ll show you exactly how to use the umask command in Linux to control default file permissions. We’ll cover everything from basic concepts to real-world security scenarios I’ve encountered in production environments.

What is the umask Command in Linux?

The umask command is a shell builtin that sets default permissions for newly created files and directories. Think of it as a permission template that automatically applies every time you create a new file.

When you run touch newfile.txt or mkdir newdir, Linux doesn’t just randomly assign permissions. Your current umask value determines what permissions those new files get.

RackNerd Mobile Leaderboard Banner

Understanding File Creation Masks

Here’s the key concept: umask is a mask that removes permissions, not one that sets them directly.

Linux starts with base permissions:

  • 666 (rw-rw-rw-) for files
  • 777 (rwxrwxrwx) for directories

Your umask then subtracts from these base permissions. If your umask is 022, the calculation works like this:

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

This filtering mechanism ensures consistent, secure defaults across your entire system.

umask vs chmod: What’s the Difference?

I get asked this constantly, so let’s clear it up once and for all.

The umask sets default permissions for new files. It’s proactive. The chmod command changes permissions on existing files. It’s reactive.

Think of umask as a template you configure once, and chmod as a tool you use to fix individual files that need different permissions.

Here’s a practical example:

$ umask 077          # Set restrictive default
$ touch secret.txt   # New file created with 600 permissions
$ chmod 644 old.txt  # Change existing file permissions

The umask ensured secret.txt was private from creation. The chmod fixed an existing file.

Why umask Matters for Security

Here’s the truth: most security breaches I’ve seen in multi-user environments trace back to overly permissive default permissions.

When your umask is too loose (like 000), every file you create is world-readable and world-writable. That database backup script you just wrote? Everyone can read your credentials. That log file your web server generates? Anyone can see user activity.

Critical scenarios where umask matters:

  • Multi-user systems: Prevent users from reading each other’s files
  • Web servers: Stop world-readable logs from leaking sensitive data
  • DevOps pipelines: Ensure CI/CD artifacts don’t expose secrets
  • Compliance: Meet security standards like CIS Security Benchmarks
  • Database backups: Keep backup files private by default

The CIS Security Benchmarks specifically recommend a umask of 027 for system accounts in security-conscious environments. That’s not arbitrary—it’s based on years of breach analysis.

How to Check Your Current umask Value

Before changing anything, you need to know your current setting. It’s a one-liner.

Viewing umask in Octal Notation

Just type umask with no arguments:

$ umask
0022

That leading zero is the special permissions bit (setuid/setgid/sticky). For most purposes, focus on the last three digits: 022.

Common default values you’ll encounter:

  • 0022 – Standard for most Linux distributions (files: 644, directories: 755)
  • 0002 – Common in collaborative environments (files: 664, directories: 775)

Viewing umask in Symbolic Mode

Prefer human-readable output? Use the -S flag:

$ umask -S
u=rwx,g=rx,o=rx

This shows the permissions that will be set on new directories. It’s the inverse of the mask itself—which I find way more intuitive for beginners.

Understanding umask Octal Notation

Let’s break down the math behind umask values. This is where it clicks for most people.

How umask Calculation Works

Each digit in octal notation represents a permission set:

PositionApplies ToExample (022)
1st digitUser/Owner0 (no permissions removed)
2nd digitGroup2 (write removed)
3rd digitOthers2 (write removed)

Each octal digit breaks down further:

  • 4 = read (r)
  • 2 = write (w)
  • 1 = execute (x)

So a umask of 022 removes write permission (2) from group and others, leaving the owner with full permissions.

Common umask Values Explained

Here are the values I use most often and when:

umaskFile PermsDir PermsUse Case
022644 (rw-r–r–)755 (rwxr-xr-x)Standard workstation, general use
002664 (rw-rw-r–)775 (rwxrwxr-x)Shared development environments
027640 (rw-r—–)750 (rwxr-x—)Security-focused servers, system accounts
077600 (rw——-)700 (rwx——)Maximum security, private files only

The 077 umask is what I use when generating SSH keys or handling sensitive credentials—completely private from creation.

Setting umask Temporarily

Want to test a different umask without committing? Just set it for your current shell session.

$ umask 077
$ touch testfile.txt
$ ls -l testfile.txt
-rw------- 1 alex alex 0 Sep 15 10:32 testfile.txt

See that? The file was created with 600 permissions (owner read/write only) because we set umask to 077.

This is perfect for one-off secure operations:

# Temporarily use restrictive umask for backup
$ umask 077
$ mysqldump -u root -p database > backup.sql
$ ls -l backup.sql
-rw------- 1 alex alex 2048576 Sep 15 10:35 backup.sql

Once you close that terminal or logout, your umask reverts to whatever’s configured in your profile.

Making umask Permanent for Your User

Temporary changes are great for testing, but you’ll want to make your preferred umask stick.

Adding umask to .bashrc

For Bash users (the most common Linux shell), edit your ~/.bashrc:

$ echo "umask 027" >> ~/.bashrc
$ source ~/.bashrc

Now every new interactive shell will use your custom umask. Verify it worked:

$ umask
0027

Perfect. From now on, new files get created with 640 permissions (rw-r—–) automatically.

Adding umask to .bash_profile or .profile

Here’s a nuance that catches people: .bashrc runs for interactive non-login shells, while .bash_profile (or .profile) runs for login shells.

For maximum coverage, I usually put umask in both:

# In ~/.bash_profile
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
umask 027

This ensures your umask applies whether you SSH in (login shell) or open a terminal window (non-login shell).

If you’re modifying config files programmatically, you might use sed for text processing to inject the umask line.

Setting umask System-Wide

Need to enforce a umask for all users on a system? You’ve got options.

Modifying /etc/profile

The traditional approach is editing /etc/profile:

$ sudo nano /etc/profile

Add near the top:

# Set default umask for all users
umask 027

This affects all users at login, but it can be overridden by individual user profiles.

Using /etc/profile.d/ for Custom Scripts

I prefer the modular approach—create a dedicated script:

$ sudo nano /etc/profile.d/umask.sh

Content:

#!/bin/bash
# System-wide umask setting
umask 027

Make it executable:

$ sudo chmod +x /etc/profile.d/umask.sh

This keeps your custom configuration isolated and easy to manage. If you need to revert, just delete this one file instead of digging through /etc/profile.

Understanding /etc/login.defs

For systems using PAM (most modern Linux distributions), check /etc/login.defs:

$ grep UMASK /etc/login.defs
UMASK           027

This sets the umask for login sessions. According to the umask man page, PAM modules can override this, so verify your actual effective umask after login.

The priority order is:

  1. PAM umask argument
  2. User GECOS field
  3. /etc/login.defs UMASK
  4. Shell profile files

Red Hat’s file permissions guide covers this in detail for enterprise environments.

Real-World umask Examples Every Admin Needs

Theory is great, but let me show you how I actually use umask in production.

Web Server Configuration Files

Web servers like Nginx and Apache create log files constantly. With a loose umask, those logs can expose sensitive data.

I set umask 027 in the web server’s systemd service file:

[Service]
User=www-data
Group=www-data
UMask=0027
ExecStart=/usr/sbin/nginx

Now all logs created by Nginx have permissions 640 (rw-r—–). The www-data user can write, the group can read, and others get nothing. Perfect for security-hardened systems.

Shell Scripts and Automation

Here’s a mistake I see constantly: automation scripts that create files with inconsistent permissions.

Always set umask at the top of your scripts:

#!/bin/bash
umask 077  # Ensure private file creation

# Generate sensitive report
echo "Secret data" > /var/reports/confidential-$(date +%Y%m%d).txt

# File is automatically 600 (rw-------)

This is especially critical for scripts scheduled with cron, which might run with a different umask than your interactive shell.

Shared Development Environments

Got multiple developers working on the same server? Use umask 002 so group members can edit each other’s files:

$ umask 002
$ touch shared-project-file.txt
$ ls -l shared-project-file.txt
-rw-rw-r-- 1 alex developers 0 Sep 15 11:45 shared-project-file.txt

Both owner and group can read/write. Others can only read. This prevents the “I can’t edit Bob’s files” problem.

CI/CD Pipeline Security

DevOps pipelines are notorious for creating files with insecure permissions. I’ve seen GitHub Actions runners create artifacts readable by all users on the build server.

In your pipeline config, explicitly set umask:

# .github/workflows/build.yml
- name: Build artifacts
  run: |
    umask 077
    ./build.sh
    tar czf release.tar.gz dist/

This ensures your build artifacts don’t leak to other users on shared runners.

Common umask Mistakes and How to Avoid Them

After years of troubleshooting permission issues, these are the errors I see most often:

Mistake 1: Setting umask too permissive (000)
Some folks think umask 000 makes life easier. It does—for attackers. Every file you create becomes world-writable. Never do this in production.

Mistake 2: Setting umask too restrictive (077) in collaborative environments
The opposite problem. Your team can’t access shared files, workflows break, frustration ensues. Match your umask to your environment.

Mistake 3: Forgetting umask is a mask, not direct permissions
New admins often think “umask 644 will give me 644 permissions.” Nope. umask 644 would remove 644 from the base permissions, giving you 022 for files (not what you wanted).

Mistake 4: Not verifying changes
Always test after changing umask:

$ umask 027
$ touch test.txt
$ mkdir test-dir
$ ls -ld test.txt test-dir
-rw-r----- 1 alex alex    0 Sep 15 12:05 test.txt
drwxr-x--- 2 alex alex 4096 Sep 15 12:05 test-dir

If the permissions don’t match expectations, you caught it early.

Mistake 5: Different umask in shell vs scripts
Your interactive shell might have umask 022, but your cron scripts might run with 077. This creates confusing permission mismatches. Always set umask explicitly in scripts.

umask Security Best Practices for 2025

Based on current security trends and compliance requirements, here’s what I recommend:

Standard workstations: umask 022
Balanced permissions. Files are readable by all, writable only by owner. Good for single-user systems.

Multi-user servers: umask 027
More restrictive. Others get no permissions. Group members can read. Recommended by the CIS Security Benchmarks.

High-security environments: umask 077
Maximum privacy. Only the owner has any permissions. Use for systems handling sensitive data.

Shared development: umask 002
Collaborative-friendly. Group members can edit each other’s work.

Additional best practices:

  • Audit user umask settings: Check ~/.bashrc files during security reviews
  • Set explicit umask in CI/CD: Don’t rely on runner defaults
  • Document your umask policy: Make it clear to your team why you’ve chosen specific values
  • Regular permission audits: Use find to locate world-writable files created accidentally
  • Balance security and usability: The most secure umask is worthless if users work around it

For troubleshooting permission-related issues after deployment, you can check system logs with journalctl to see if permission denied errors are occurring.

The POSIX umask specification defines the standard behavior across Unix-like systems, so these practices apply whether you’re on Linux, BSD, or macOS.

Remember: umask is just one layer of security. Combine it with proper firewall configuration, regular updates, and the principle of least privilege for defense in depth.

The bottom line? Set your umask deliberately, test it thoroughly, and make it permanent. Your future self—and your security team—will thank you.