Users, groups and permissions in practice: ownership, umask and the effective identity
How a process's effective identity, the mode bits and umask decide file access.

A process never touches a file “as its human owner”. The kernel gives it an identity — a user ID, an effective group ID and a set of supplementary groups — and compares that with the file’s owner, group and mode bits. Most “permission denied” incidents are a mismatch between the identity a process actually has and the ownership someone assumed, not a broken filesystem.
The identity the kernel actually uses
The permission bits are three groups of three. Which of the three groups applies is decided by a single rule:
- the first group applies when the process’s effective user ID equals the file’s owner ID;
- the second applies when the file’s group ID equals the process’s effective group ID, or is one of the process’s supplementary group IDs;
- otherwise the third group applies.
So group membership is not a property of the file, it is evaluated against the groups the process currently carries. On Linux the IDs used for path resolution are specifically the filesystem user and group IDs together with the supplementary groups, and the kernel keeps the filesystem ID in step whenever the effective ID changes. After login the real and effective IDs usually coincide; sudo raises the effective ID for the command it runs, and a setuid program raises it at execve. id prints the result — the uid, the gid and the groups — which answers “as whom does this actually run?” better than reading /etc/passwd.
Ownership and the mode bits
chown sets the owner and/or the group: chown alice:web file changes both, chown alice file only the owner, and --reference copies them from another file. Who may do it is narrowly defined: only a privileged process (one with CAP_CHOWN) may change a file’s owner, while the owner may move the file to any group they are a member of.
chmod writes the mode. It accepts a symbolic form, [ugoa...][[-+=][perms...]...] (with perms from rwxXst), or an octal number of one to four digits: the first digit sets setuid (4), setgid (2) and the sticky bit (1), and the next three select user, group and other. stat -c '%a %U %G' file prints the mode in octal and the two owner names, which is the fastest way to compare “what someone remembered” with what is on disk.
For a directory the three bits mean something slightly different: x is the right to traverse it, r to list its entries, w to add or remove entries. A file can be readable while its directory is not traversable, and the error is the same EACCES.
umask: the mode a new file is born with
A new file does not get the mode you might expect. Creation calls start from a base mode — 0666 for a regular file, 0777 for a directory — and the process’s umask turns bits off from the requested mode. With the common default 022, a file created with 0666 becomes 0644, that is rw-r--r--. A server account running with 077 produces 0600 files, readable and writable by its owner alone. The umask is inherited by child processes across fork and left unchanged by execve, so a mask set in a shell spreads to everything the shell starts.
sudo and the effective identity
sudo executes a command as another user (root by default) according to the policy in sudoers: a rule names a user or a %group, the hosts it applies to, an optional (runas) target and the commands allowed, with NOPASSWD: to skip the password. Authentication is cached per terminal for five minutes by default. The part that matters for permissions is what happens after the check: the command runs with the runas user’s effective identity, and it is that identity the kernel compares with the file’s bits — not the human who typed the command. sudo -i opens a shell as that user, sudo -u runs one command as a named user.
The special bits
- setuid (
4) on a regular file — atexecvethe process’s effective user ID becomes the file owner’s, giving the program the owner’s rights. This is the mechanism behind classic privileged helpers, and the reason a setuid binary is security-sensitive. - setgid (
2) on a regular file — the same idea for the group: the effective group ID becomes the file’s group. - setgid (
2) on a directory — Linux applies BSD semantics when the directory’s setgid bit is set, so the group ID of a new file inside it is taken from the parent directory rather than from the creating process. This is how shared team directories keep a stable group. - sticky (
1) on a directory — with it set, an unprivileged user may not remove or rename an entry they do not own, which is what makes a world-writable/tmpusable.
Two quiet removals to remember: changing an executable’s owner or group as an unprivileged user clears its setuid and setgid bits, and a filesystem mounted nosuid — or a process under no_new_privs — makes those bits ineffective regardless of what chmod shows.
What actually bites in practice
- “I added the account to the group”. Adding a user to a group does not rewrite any file’s group, and the check uses the group set a process was given when it started: a new login session picks the membership up, a service already running does not.
- A hardened umask you forgot about. A service started with
umask 077writes0600files; a second account on the same host, however well grouped, cannot read them. - A setuid helper that is not one. The bit is there, the mount is
nosuid, and the program quietly runs with the caller’s identity.
Level and prerequisites
L2 — operational: read an identity, read a mode, and explain which one decided an access. Prerequisites are the L1 file-and-directory model and basic shell use; access-control lists, SELinux contexts and PAM belong to other sheets.
Where to go next
- Knowledge — the index.
- Server and virtualization — the area this sheet belongs to.
- Operating systems — this sheet’s node, together with the filesystem and mounting sheet.
References
- GNU coreutils — chmod(1) — https://man7.org/linux/man-pages/man1/chmod.1.html — the symbolic form
[ugoa...][[-+=][perms...]...], the octal form with setuid (4), setgid (2) and sticky (1) in the first digit, the meaning ofX/s/t, and the sticky-bit effect on directories. - GNU coreutils — chown(1) — https://man7.org/linux/man-pages/man1/chown.1.html —
chownsyntax for owner-only, owner-and-group and--referencechanges. - Linux man-pages — umask(2) — https://man7.org/linux/man-pages/man2/umask.2.html — the mask turns bits off from the mode argument of
open(2)/mkdir(2), the default022, and the worked example0666 & ~022 = 0644. - Linux man-pages — path_resolution(7) — https://man7.org/linux/man-pages/man7/path_resolution.7.html — the three-class rule (effective user ID, effective or supplementary group IDs, otherwise other) and the
EACCESreturned when a directory is not searchable. - Linux man-pages — credentials(7) — https://man7.org/linux/man-pages/man7/credentials.7.html — real/effective/saved IDs, the Linux-specific filesystem user and group IDs that determine file access together with the supplementary groups, and the set-user-ID behaviour.
- Linux man-pages — execve(2) — https://man7.org/linux/man-pages/man2/execve.2.html — a set-user-ID file gives the process the effective user ID of the file’s owner and the analogous group behaviour.
- Linux man-pages — open(2) — https://man7.org/linux/man-pages/man2/open.2.html — the group ID of a new file follows the parent directory’s group when the directory has the set-group-ID bit set (BSD semantics).
- Linux man-pages — chown(2) — https://man7.org/linux/man-pages/man2/chown.2.html — only a privileged process (
CAP_CHOWN) may change the owner; the owner may change the group among their own groups; the setuid/setgid bits are cleared when an unprivileged user changes an executable’s owner or group. - Linux man-pages — group(5) — https://man7.org/linux/man-pages/man5/group.5.html — the group database, its fields and the membership list.
- Linux man-pages — passwd(5) — https://man7.org/linux/man-pages/man5/passwd.5.html — the account database, and the shadow-password arrangement where
/etc/passwdholdsxand the encrypted passwords live in/etc/shadow, readable by the superuser only. - sudo — sudo(8) — https://man7.org/linux/man-pages/man8/sudo.8.html — “execute a command as another user” and the per-terminal five-minute credential cache.
- sudo — sudoers(5) — https://man7.org/linux/man-pages/man5/sudoers.5.html — the user-specification syntax with
%groupentries, the(runas)list andNOPASSWD:. - GNU coreutils — id(1) — https://man7.org/linux/man-pages/man1/id.1.html — real and effective user and group IDs, and the
-u/-g/-Goptions with-r; the identity a process actually carries. - GNU coreutils — stat(1) — https://man7.org/linux/man-pages/man1/stat.1.html —
-c/--format, and the%a(permission bits in octal),%U(user name of owner) and%G(group name of owner) directives used in the body.