The problem
Permissions only come up when something is already broken.
Nobody studies file modes for fun. You meet them at the worst moment: a deploy script that
won't run, a web server throwing 403 Forbidden, or SSH slamming the door on
the key you've used for months. The terminal answers in a code you half-remember — and
the top search result cheerfully suggests chmod 777, which “fixes” it
by handing write access to every user and process on the machine.
$ ssh -i ~/.ssh/id_ed25519 deploy@server
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '~/.ssh/id_ed25519' are too open.
It is required that your private key files are
NOT accessible by others.
The message even names the culprit — 0644 — but only helps if you can
read it. That's the whole gap this page closes.
The core idea
It's just nine switches. Each row of three is one octal digit.
A classic mode is a 3×3 grid: rows for owner, group and
others; columns for read, write and
execute. Weight the columns 4, 2, 1 and
add up each row — that sum is the digit. Three rows, three digits: a mode.
- Owner 4 + 2 + 1 7 Owner: read, write and execute all set — 4 plus 2 plus 1 equals 7.
- Group 4 + 0 + 1 5 Group: read and execute set, write withheld — 4 plus 0 plus 1 equals 5.
- Others 4 + 0 + 1 5 Others: read and execute set, write withheld — 4 plus 0 plus 1 equals 5.
One honest wrinkle: on a directory, x doesn't mean
“run it” — it means enter and traverse it. permbits has a
file / directory switch precisely because the plain-English meaning changes.
Reading the wire format
An ls -l mode field, pulled apart character by character.
The cryptic 10-or-11 character string at the start of every ls -l line is the
same grid again, flattened — plus a type character in front and, sometimes, extra letters.
Here's a spicy one: a shared project directory.
drwxr-sr-x+ = octal 2755, a setgid directory — new files inside inherit the directory's group. The trailing + says ACLs are also in play; permbits detects it and tells you it's beyond the classic bits, never silently drops it.
The string d r w x r dash s r dash x plus splits into: d for directory; rwx for the owner, digit 7; r dash s for the group with the setgid bit, digit 5 plus the 2000 special bit; r dash x for others, digit 5; and a trailing plus meaning ACLs beyond the classic bits.
Paste any such line — or a whole ls -l row — into permbits and it renders
the grid, the octal, the special bits (s/S/t/T)
and a plain-English sentence per class.
Back to that SSH key
The fix is two switches. Watch 644 → 600.
0644 means group and others can read your private key. OpenSSH refuses
to use it until they can't. So: flip off the two read switches that don't belong to you.
The cited recipe
chmod 600 ~/.ssh/id_ed25519
Owner keeps read + write (6); group and others get nothing (0,
0). In permbits this is one of 24 hand-verified recipes —
each with the command, a one-line why, the upstream source quote (OpenSSH, GNU Coreutils,
POSIX, AWS, WordPress, sudoers) and a verified-on date. AWS .pem keys get the
stricter chmod 400 variant.
Animation: on the 644 grid, the group-read and others-read switches turn off, leaving 600 — owner read and write only.
Where defaults come from
umask: the bits your system withholds from every new file.
New files don't get their mode by magic. The system starts from 666 for files and
777 for directories, then subtracts whatever your umask lists.
That's the whole trick:
666 & ~ 022 = 644
rw-r--r--
777 & ~ 022 = 755
rwxr-xr-x
022 withholds write from group and others — the everyday default.
077 withholds everything from everyone but you. permbits has a umask
panel with the arithmetic spelled out and one-tap 022/002/077.
Enforced, not promised
Paste a production ls -l line. It cannot leave this tab.
runs in this browser
never reached
File listings leak real information — usernames, hostnames, project paths. Both this page
and the permbits calculator ship a strict Content-Security-Policy with
connect-src 'none': the browser itself blocks every network
request, so privacy is enforced by the platform, not promised in a policy page. No fonts,
scripts, images or analytics load from anywhere else. The calculator's only storage is your
own browser's localStorage, for your last mode and recent recipes.
What the calculator does
A short tour of permbits.
-
Four-way converter
Edit the octal, the symbolic string, the checkbox grid or the special-bit toggles — every other view updates live, with the exact
chmodcommand ready to copy. -
ls -l paste parser
Paste a full line or just the mode field. Type chars,
s/S/t/Tletters and the+ACL marker are all read and explained — never silently dropped. -
Symbolic clause applier
Type
u+x,go-w,a=rXoru=rw,go=and see before → after with the changed slots highlighted. -
Umask panel
Any umask, with the file (
666 & ~umask) and directory (777 & ~umask) arithmetic spelled out. One-tap 022 / 002 / 077. -
24 cited recipes
SSH keys, web permissions, setgid team dirs, sudoers… each with the command, why, an upstream citation and a verified-on date, plus a load-into-calculator button. Distro-variable entries are flagged beta.
-
Plain English + warnings
One honest sentence per class for the current mode, file-vs-directory semantics both stated, and a warning badge on risky modes like 777 or setuid + world-writable. Printing renders a one-page cheat sheet.
Now decode the real thing.
Paste your own ls -l line, flip the switches, grab the cited command.
Free, offline, no accounts — and it tells no one what you pasted.
sreenivas-sadhu-prabhakara.github.io/permbits