Chmod 600 – Linux Permission Guide

What It Means, Explanation, How to Use, When to Use & More

chmod 600

The Private File Standard

🔑 Fix the SSH key warning
"UNPROTECTED PRIVATE KEY FILE!" — here's the fix
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for 'mykey.pem' are too open. This private key will be ignored. Permission denied (publickey).
Run this:
chmod 600 mykey.pem Copy

Replace mykey.pem with your actual key filename. If you're on Windows and this doesn't work, see the Windows section below — NTFS handles permissions differently and needs a different fix.

Apply to a Single File
chmod 600 [filename] Copy
Apply to All .pem Key Files in Current Directory
chmod 600 *.pem Copy
Verify It Worked
ls -l [filename] Copy

What does chmod 600 mean?

In Linux, 600 is an octal representation of file system permissions that gives the owner read and write access and blocks everyone else completely. It's the standard for any file that should stay private and doesn't need to be executed — SSH keys, .env files, API credentials, and other secrets.

User (6)

Read + Write
The owner can view and edit the file. No execute permission — this isn't for scripts.

Group (0)

No Access
Users in the file's group cannot read, modify, or even list the contents.

Others (0)

No Access
Every other user on the system is completely locked out.

The quick way to think about it

600 is the answer to the question: "What's the strictest permission I can give a file that I still need to edit?" If you don't need to edit it, go down to 400 (read-only). If you need to execute it, go up to 700. If someone else needs to read it, go to 640 or 644.

Why "600"? How the Numbers Work

Every digit in a chmod code is the sum of three values:

4
Read (r)
2
Write (w)
1
Execute (x)

Add them together to build any permission digit:

6 = 4 + 2 read + write (no execute)
0 = 0 no access at all
4 = 4 read only
7 = 4 + 2 + 1 read + write + execute

So 600 reads as: 6 for owner (read + write), 0 for group (nothing), 0 for others (nothing).

Permission Matrix (rw-------)

Level Read (r) Write (w) Execute (x)
Owner
Group
Others

Numeric vs Symbolic Notation

chmod accepts two equivalent styles. All three commands below produce identical results:

# Numeric (octal) — the one most tutorials show chmod 600 id_rsa # Symbolic — set exactly these bits chmod u=rw,go= id_rsa # Symbolic — grant rw to owner, strip everything from group and others chmod u+rw,go-rwx id_rsa

Letters used in symbolic mode: u = user (owner), g = group, o = others, a = all. Operators: + adds a permission, - removes it, = sets it exactly.

How to Verify It Worked

After running chmod, check with ls -l:

$ chmod 600 id_rsa $ ls -l id_rsa -rw------- 1 alice alice 3381 Apr 17 14:32 id_rsa # First character: "-" = file, "d" = directory # Next 3 chars: owner permissions (rw- = read+write, no execute) # Next 3 chars: group permissions (--- = none) # Last 3 chars: others permissions (--- = none)

The six trailing dashes are what you're looking for — they confirm no one but you can touch the file. You can also check numerically with stat -c "%a %n" id_rsa, which should print 600.

The SSH Private Key Use Case

OpenSSH strictly enforces that private key files are readable only by their owner. If any other user on the system could read your key, anyone who compromised that user account could steal your key — so SSH refuses to use it at all. This enforcement is controlled by the StrictModes yes setting in sshd_config, which is on by default.

The moment your key's permissions slip to 644, 664, 755, or anything else group- or world-readable, you'll see this:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for '/home/alice/.ssh/id_rsa' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key "/home/alice/.ssh/id_rsa": bad permissions alice@host: Permission denied (publickey).

The complete recipe for a healthy ~/.ssh directory:

# The .ssh directory itself — only owner can enter (note: 700, not 600) chmod 700 ~/.ssh # Private keys — owner read/write only chmod 600 ~/.ssh/id_rsa chmod 600 ~/.ssh/id_ed25519 chmod 600 ~/.ssh/*.pem # Public keys, authorized_keys, known_hosts — readable is fine chmod 644 ~/.ssh/id_rsa.pub chmod 644 ~/.ssh/id_ed25519.pub chmod 644 ~/.ssh/authorized_keys chmod 644 ~/.ssh/known_hosts # SSH client config chmod 600 ~/.ssh/config
Should I use 600 or 400 for my private key?

Both work — SSH accepts either. 600 lets you edit the file (e.g., to add a passphrase later with ssh-keygen -p). 400 is read-only, which is slightly safer against your own fat-fingered commands. Most people use 600. Security-conscious folks use 400 and switch to 600 temporarily when they need to modify the key.

AWS EC2 .pem Keys (The Most Common Scenario)

If you just downloaded a key from the AWS console and tried to SSH into your EC2 instance, you almost certainly hit the "UNPROTECTED PRIVATE KEY FILE" warning. Files downloaded from a browser land in ~/Downloads with default permissions around 644 — too loose for SSH.

The fix, start to finish:

# 1. Move or navigate to where your .pem file lives cd ~/Downloads # 2. Lock it down chmod 600 my-ec2-key.pem # 3. Verify ls -l my-ec2-key.pem # Should show: -rw------- 1 you you 1675 ... my-ec2-key.pem # 4. SSH in (use the right default user for your AMI) ssh -i my-ec2-key.pem ec2-user@ # Default users by AMI: # Amazon Linux → ec2-user # Ubuntu → ubuntu # Debian → admin (older: debian) # RHEL / CentOS → ec2-user (older RHEL: root) # SUSE → ec2-user # Bitnami → bitnami
Recommended: move the key out of Downloads

Keys in ~/Downloads tend to get deleted when you clean up the folder. Move it somewhere deliberate: mkdir -p ~/.ssh && mv my-ec2-key.pem ~/.ssh/ && chmod 600 ~/.ssh/my-ec2-key.pem. Then connect with ssh -i ~/.ssh/my-ec2-key.pem ec2-user@…

Windows: Why chmod 600 Often Doesn't Work

This trips up a lot of people new to SSH on Windows. You ran chmod 600 mykey.pem in Git Bash, it completed silently, and yet SSH still throws "UNPROTECTED PRIVATE KEY FILE." The reason: Windows filesystems use NTFS ACLs, not Unix permission bits. Git Bash and WSL try to emulate chmod, but the emulation doesn't always stick, and the OpenSSH client on Windows reads the real NTFS ACLs — not the fake Unix bits.

The real fix on Windows is to remove all inherited permissions and grant access only to your user. Three ways to do that:

PowerShell with icacls (recommended)

The most reliable method. Run from PowerShell or Command Prompt in the folder with your key:

icacls mykey.pem /inheritance:r
icacls mykey.pem /grant:r "%username%:R"

The first line removes all inherited permissions. The second grants read-only access to your user. After this, SSH will accept the key.

File Properties → Security

  1. Right-click the .pem file → Properties
  2. Open the Security tab → Advanced
  3. Click Disable inheritance → choose Remove all inherited permissions
  4. Back on the Security tab, click Edit and add only your own user with Read permission
  5. Click OK on all windows

Use WSL (Linux on Windows)

If you have WSL installed, chmod 600 works properly inside the WSL filesystem (~/). Move the key into your WSL home directory, chmod it there, and SSH from WSL:

cp /mnt/c/Users/you/Downloads/mykey.pem ~/
chmod 600 ~/mykey.pem
ssh -i ~/mykey.pem ec2-user@host

Don't chmod and keep the key on the Windows side — it won't stick reliably.

Using PuTTY instead of OpenSSH?

PuTTY doesn't use .pem files directly. Convert your key with PuTTYgen (Load → select the .pem → Save private key as .ppk). PuTTY doesn't care about chmod permissions — it reads the .ppk file directly. No "UNPROTECTED PRIVATE KEY" warning because PuTTY isn't OpenSSH.

Other Files That Should Be chmod 600

Any file containing credentials, tokens, or secrets belongs at 600 (or stricter). Here's the checklist:

~/.ssh/id_rsa, ~/.ssh/id_ed25519, *.pem SSH private keys — required by OpenSSH
~/.ssh/config SSH client config — may contain hostnames and key paths
.env Application environment files (Node, Laravel, Rails, Django) — usually hold database passwords and API keys
~/.aws/credentials AWS CLI credentials — access keys to your entire cloud account
~/.netrc curl/wget/git credentials — some tools refuse to read it unless it's 600
~/.pgpass PostgreSQL password file — psql ignores it if permissions are too loose
wp-config.php WordPress database credentials (600 for full lockdown, or 640 if PHP-FPM runs as a different user)
/etc/ssl/private/*.key TLS/SSL certificate private keys (on some systems these are owned by root and need sudo)
~/.gnupg/* GPG private keyring (GPG usually sets these automatically; 600 on files, 700 on the directory)

600 vs 400 vs 700 — The Private Trio

These three permissions all mean "only the owner has access" — but they're different in subtle ways that matter. This is the #1 source of confusion in SSH guides.

400
-r--------
Read-Only

Owner can read but not modify. Best for keys and configs you never intend to edit. Slightly safer — you can't accidentally overwrite it.

600
-rw-------
Read + Write

Owner can read and edit. The everyday standard for private files. Use this for .env, .pem, wp-config.php, and anything you may need to modify.

700
-rwx------
drwx------
Read + Write + Execute

Adds the execute bit. Required for directories (so you can cd into them) and for private scripts you need to run. Never needed for plain data files.

Quick rule of thumb

Plain file you edit? 600. Key file you never touch again? 400. A directory or a script? 700.

chmod 600 vs Other Common Permissions

Code Symbolic Typical Use
400 -r-------- Owner read-only. SSH keys you never plan to modify, extra-safe config files
600 -rw------- Private files. SSH keys, .env, .aws/credentials, wp-config.php, any secret you need to edit
640 -rw-r----- Owner edits, group reads, others locked out. Use on VPS where a service (web server, database) needs to read the file but nobody else should
644 -rw-r--r-- Default for regular files — owner edits, everyone reads. Correct for public content, wrong for secrets
700 -rwx------
drwx------
Owner full access. Use for private directories (so you can cd into them) and executable scripts
666 -rw-rw-rw- Avoid. Everyone on the system can read and write. Never appropriate for real files

Can You Use chmod 600 on a Directory?

Technically yes — but you almost never should. Directories need the execute bit (1) to be enterable. A directory at 600 looks like this:

$ chmod 600 secret-folder $ ls -l drw------- 2 alice alice 64 Apr 17 14:32 secret-folder $ cd secret-folder bash: cd: secret-folder: Permission denied $ ls secret-folder ls: cannot access 'secret-folder/file': Permission denied

You can see the folder exists and list its entries by name, but you can't enter it or read any of its files. For a private directory, use 700 instead — that's what 700 was designed for.

⚠ Don't run chmod -R 600 on a directory tree

You'll strip the execute bit from every subdirectory and lose the ability to navigate into any of them. To fix a tree of secrets, use: find /path -type d -exec chmod 700 {} \; and find /path -type f -exec chmod 600 {} \;

Ownership Matters Too

600 only protects the file if the right user owns it. A key file at 600 owned by root is useless to you as a regular user — you can't read it, and SSH tries to read it as you.

$ ls -l mykey.pem -rw------- 1 root root 1675 Apr 17 14:32 mykey.pem # Permissions are correct, but root owns it — you can't read it. $ sudo chown $USER:$USER mykey.pem $ ls -l mykey.pem -rw------- 1 alice alice 1675 Apr 17 14:32 mykey.pem # Now you own it and the 600 protects it for you.

Common pattern: you copied a key with sudo cp, which made root the owner. Fix with sudo chown $USER:$USER filename.

Troubleshooting

WARNING: UNPROTECTED PRIVATE KEY FILE! Your SSH private key is readable by other users.

Run chmod 600 [keyfile] (or 400). If you're on Windows and it still fails, see the Windows section above — you need icacls, not chmod.

bad permissions: ignore key: /home/user/.ssh/id_rsa Same issue, older SSH wording.

Identical fix: chmod 600 ~/.ssh/id_rsa. Also verify the ~/.ssh directory itself is 700 and that your home directory isn't group- or world-writable (chmod 755 ~ or stricter).

Permission denied (publickey) after chmod 600 The permissions are fixed but authentication still fails.

chmod fixes the "too open" error but doesn't fix every SSH problem. Check: (1) you're using the right username for the AMI (ec2-user, ubuntu, admin, etc.), (2) the public key is in ~/.ssh/authorized_keys on the server, (3) the key you're using actually matches that server. Run ssh -v -i yourkey user@host for verbose debugging.

chmod 600 runs silently on Windows but SSH still complains NTFS doesn't honor Unix permissions — chmod in Git Bash is mostly cosmetic.

Use PowerShell with icacls instead: icacls mykey.pem /inheritance:r followed by icacls mykey.pem /grant:r "%username%:R". See the Windows section above for details.

chmod: Operation not permitted You don't own the file.

Use sudo chown $USER:$USER filename first, then chmod 600 filename. If it's a system file owned by root for good reason, use sudo chmod 600 filename to change it as root.

psql: .pgpass is insecure / ignored PostgreSQL's password file must be 600 or it's ignored silently.

Run chmod 600 ~/.pgpass. Same rule applies to ~/.netrc for curl/git.

Files keep reverting after upload or git pull Either your FTP/SFTP client is rewriting permissions, or git doesn't track permission changes by default.

For git, enable filemode tracking: git config core.fileMode true. But git only tracks execute bit changes — 600 vs 644 isn't tracked at all. For sensitive files in a repo, set permissions locally in your deploy script, not through git.

Frequently Asked Questions

Should I use 600 or 400 for my SSH private key?

Both satisfy OpenSSH's security check. 600 lets you edit the key (e.g., to add a passphrase later). 400 is read-only and slightly safer against accidental overwrites. 600 is the common default; 400 is the paranoid default. Either works.

600 vs 700 — what's the difference?

The execute bit. 600 has no execute permission (suitable for data files like keys and .env). 700 includes execute (suitable for scripts and directories, since directories need execute to be traversable). For a private key file: 600. For a private ~/.ssh folder: 700.

Does chmod 600 work on Windows?

Not really. Windows uses NTFS ACLs, not Unix permission bits. Running chmod 600 in Git Bash often appears to succeed but doesn't actually restrict access in a way OpenSSH on Windows recognizes. Use icacls in PowerShell, or move the key into WSL and chmod it there. See the Windows section above.

Is 600 enough for storing API keys and passwords?

600 is the right filesystem permission, but filesystem permissions aren't the whole story. If you have full-disk encryption, stolen laptops are fine. Without it, anyone with physical access to the drive can read 600 files by mounting the drive elsewhere. For very sensitive secrets, combine 600 with disk encryption (LUKS, FileVault, BitLocker) or a secret manager (1Password, Vault, AWS Secrets Manager).

Can root still read my 600 files?

Yes. The root user bypasses all standard permission checks. chmod 600 protects against other regular users — not against root, the kernel, or anyone with physical disk access. On your own laptop, that means you can always read your own files by using sudo. If you need protection from root, use encryption (GPG, age) on top of permissions.

Why do some guides say 644 for authorized_keys but 600 for id_rsa?

Because they're different files. id_rsa is your private key — nobody else should read it (600). authorized_keys holds public keys that are safe to share, but the file itself lives on the server where SSH wants it readable but not writable by others (644 — or 600 for extra strictness; both work).

Why does my .env file default to 644 when I create it?

That's your umask. Most systems default to umask 022, which creates new files as 644. Change yours to umask 077 (add to ~/.bashrc) and new files will default to 600. Just remember this affects all newly-created files, not just secrets.

Can I use 600 on a directory?

Technically yes, but it's almost never what you want. A directory at 600 is visible but not enterable — you can't cd into it. Use 700 for private directories. 700 is to directories what 600 is to files.

Do I need sudo to run chmod 600?

Only if you don't own the file. Your own files (in your home directory, typically) you can chmod freely. Files in /etc/, /var/, or owned by root or another user require sudo.

Scroll to Top