chmod 444 sets the mode to r--r--r--: the owner, the group and everyone else can read (4), and nobody can write or execute. It marks a file as not to be edited in place: generated output, released artifacts, reference data, files a build fetched and must not change.
Where you’ll meet it
- Go’s module cache. The
gocommand makes downloaded modules read-only, sorm -rfon the cache fails withPermission denied;go clean -modcacheremoves it, andgo build -modcacherwleaves new downloads writable. - The Nix store. Files under
/nix/storeare444, or555when executable. - Docker Swarm secrets, mounted under
/run/secrets/as0444unless the service setsmode.
Editors notice: vim opens a 444 file read-only and warns W10: Warning: Changing a readonly file on the first edit.
What it doesn’t protect against
- Deletion and replacement. Both depend on the directory.
rmasksremove write-protected regular file?and then deletes it, andsed -iormv new.txt file.txtswaps in a new file without ever writing to the old one. - The owner. The owner can always
chmod u+wit back. - Root, whose reads and writes ignore the permission bits.
- Readers. Everyone can read it, so it’s no place for secrets;
400keeps it to the owner.
chmod -R 444 locks you out
A directory needs execute to be entered. chmod -R 444 dir takes execute off the directories too, so nobody but root can open anything inside them, the owner included. To make a tree read-only, take write away and leave execute alone:
chmod -R a-w dir # 644 files become 444; 755 files and directories 555
find dir -type f -exec chmod 444 {} + # or set files only, leaving directories as they are
stat -c '%a %n' dir/report.csv # 444 dir/report.csv
To reverse the first command, chmod -R u+w dir.
In git and Kubernetes
Git can’t store 444: it records 100644, and checkout recreates the file as 644 under umask 022. Apply read-only modes after checkout, or in the build that generates the files.
In Kubernetes, Secret and ConfigMap volumes are mounted read-only whatever the mode, so defaultMode: 0444 (292 in JSON) behaves like the default 0644: any user in the container can read the files, and nobody can write them.