Linux Users, Groups, Permissions & Privileges — Understanding Who Can Do What
When I started working with Linux, I kept seeing commands like:
ls -l
chmod
chown
sudo
whoami
id
groupsI knew that they were related to permissions, but I didn’t really understand what was happening underneath.
Then I started asking a much simpler question:
When a Linux process tries to access a file, how does Linux decide whether to allow or deny it?
That question leads us into one of the most important parts of Linux:
Users, groups, ownership, permissions, and privileges.
The Big Picture
Let’s start with the complete mental model:
USER
│
▼
User / Groups
│
▼
PROCESS
│
│ tries to access
▼
FILE
│
┌─────┴─────┐
▼ ▼
Owner Group
│ │
└─────┬─────┘
▼
Permissions
│
▼
Linux Kernel
│
┌─────┴─────┐
▼ ▼
ALLOW DENY1. What Is a Linux User?
A user is an identity recognized by Linux.
For example:
alice
bob
devops
ubuntu
rootWhen you log into a Linux server:
ssh alice@serverLinux identifies you as:
aliceBut internally, Linux doesn’t primarily identify users by their names.
It uses a number:
UID — User ID
For example:
alice → UID 1001
bob → UID 1002
root → UID 0This is important.
Linux ultimately cares about the UID, not simply the username.
2. The Root User
You’ve probably heard of:
rootRoot is the most privileged traditional Linux user.
The root user normally has:
UID = 0This is why you’ll often see:
id rootreturn something similar to:
uid=0(root) gid=0(root) groups=0(root)Root can perform operations that ordinary users cannot.
For example:
rm -rf /some/protected/directoryA normal user might receive:
Permission deniedwhile root may be allowed to perform the operation.
But this leads to an important security principle:
Don’t use root privileges when you don’t need them.
We’ll see why later.
3. How Does Linux Know About Users?
User information is commonly stored through files such as:
/etc/passwdYou can inspect it:
cat /etc/passwdYou might see:
root:x:0:0:root:/root:/bin/bash
alice:x:1001:1001:Alice:/home/alice:/bin/bash
bob:x:1002:1002:Bob:/home/bob:/bin/bashEach line describes a user account.
For example:
alice:x:1001:1001:Alice:/home/alice:/bin/bashcontains information such as:
username
UID
GID
home directory
login shellModern Linux systems can also obtain user information from external identity systems such as LDAP or Active Directory through NSS, so /etc/passwd isn't necessarily the only source of user identities.
For learning Linux, though, /etc/passwd is a good starting point.
4. What Is a Group?
Now imagine you have 20 developers.
You don’t want to individually configure permissions for every developer.
Instead, you can create a group:
developersThen:
Alice ──┐
Bob ──┼──→ developers
John ──┤
Sara ──┘Now you can give permissions to the group.
For example:
/opt/application/could belong to:
root:developersand developers could have appropriate access through the group.
5. GID — Group ID
Just as users have UIDs, groups have:
GID — Group ID
For example:
developers → GID 2001You can see your groups with:
groupsOr:
idFor example:
uid=1001(alice) gid=1001(alice) groups=1001(alice),2001(developers)Now we can interpret it:
UID 1001
↓
Alice
GID 1001
↓
Alice's primary group
GID 2001
↓
developers group6. Primary and Supplementary Groups
A Linux user can belong to multiple groups.
For example:
Alice
│
├── Primary group → alice
│
├── Supplementary → developers
│
├── Supplementary → docker
│
└── Supplementary → monitoringCheck with:
id aliceThis becomes very useful in DevOps.
For example, a user might belong to:
dockerwhich allows them to interact with the Docker daemon according to the system’s configuration.
7. Now Let’s Look at a File
Run:
ls -lYou might see:
-rw-r----- 1 alice developers 1024 Aug 31 10:00 config.yamlThis line contains a lot of information.
Let’s focus on:
-rw-r-----and:
alice developersThe ownership is:
Owner → alice
Group → developersThe permissions are:
-rw-r-----Let’s break that down.
8. Understanding r, w, and x
Linux has three basic permissions:
r = read
w = write
x = executeThey can be represented numerically:
r = 4
w = 2
x = 1Why?
Because:
4 + 2 + 1 = 7So:
rwx = 7
rw- = 6
r-x = 5
r-- = 4
-wx = 3
-w- = 2
--x = 1
--- = 0We’ll use this when we learn chmod.
9. User, Group, Others
Linux divides permission checks into three categories:
USER
GROUP
OTHERSFor example:
-rwxr-xr--Break it into:
- | rwx | r-x | r--
│ │ │
│ │ └── Others
│ └──────── Group
└────────────── OwnerSo:
Owner → rwx
Group → r-x
Others → r--This is one of the most important Linux permission concepts.
10. What Does -rwxr-xr-- Mean?
Let’s translate it.
Owner
rwxThe owner can:
read
write
executeGroup
r-xThe group can:
read
executebut cannot:
writeOthers
r--Everyone else can:
readbut cannot:
write
execute11. The First Character
Don’t forget the first character:
-rwxr-xr--
^The first character represents the file type.
For example:
- regular file
d directory
l symbolic linkSo:
-rwxr-xr--means:
- → regular file
rwx → owner permissions
r-x → group permissions
r-- → others permissionsWhile:
drwxr-xr-xmeans:
d → directory
rwx → owner
r-x → group
r-x → others12. Directory Permissions Are Different
This is where many beginners get confused.
For a file:
r → read contents
w → modify contents
x → executeBut for a directory, the meaning changes.
Directory r
Allows you to list directory entries.
ls directoryDirectory w
Allows you to create, delete, or rename directory entries, subject to the other permission requirements.
Directory x
Allows you to traverse/access the directory.
For example:
cd /datarequires execute permission on the directory.
So:
Directory:
r → list
w → create/delete/rename entries
x → enter/traverseThis is extremely important.
13. Here’s a Real Example
Suppose:
/datahas:
drwxr-x---And:
owner = root
group = developersThen:
root
↓
rwx
developers
↓
r-x
others
↓
---A developer can:
list files ✅
enter directory ✅
create files ❌
delete files ❌Why?
Because the group has:
r-xbut not:
w14. How Does Linux Actually Decide?
Now we’re getting to the most important part.
Suppose:
Alicetries to read:
ls /opt/app/config.yamlLinux doesn’t simply ask:
“Does this file have read permission?”
It asks:
“Does this particular process have permission to read this particular file?”
When Alice types:
lsLinux needs to execute the ls program.
So Linux creates a process:
Alice (user)
│
│ runs
▼
ls
│
▼
Process
PID = 1234So:
A user is an identity. A process is a running instance of a program.
How Does Linux Know the Process Belongs to Alice?
This is the key.
When Linux creates the process, the process gets a UID associated with it.
Suppose Alice has:
Alice
UID = 1001Alice runs:
lsLinux creates:
Process
PID = 1234
UID = 1001So we can think of it as:
Alice
UID 1001
│
│ starts
▼
ls process
PID 1234
UID 1001The process doesn’t simply carry the word "alice" around.
The kernel uses credentials such as:
UID
GID
Supplementary groupsto determine what the process is allowed to do.
Linux checks the process identity against the file ownership and permissions.
Conceptually:
Process
│
├── UID = 1001
└── Groups = 1001, 2001
│
▼
File ownership
│
┌────┼────┐
▼ ▼ ▼
Owner Group Others
│ │ │
└────┼────┘
▼
Permissions
│
▼
ALLOW / DENY15. An Important Rule
Linux doesn’t normally combine:
owner permissions
+
group permissions
+
others permissionsInstead, the permission class that applies to the process is selected.
For example:
-rw-r-----
alice developersIf Alice accesses it, she is the owner, so Linux uses:
rw-If Bob is a member of developers but isn't Alice:
r--is used.
If Charlie is neither Alice nor a member of developers:
---is used.
This is a crucial concept.
16. chmod
Now we can finally understand:
chmodchmod means:
change mode
For example:
chmod u+x script.shmeans:
u → user/owner
+ → add
x → executeSo:
Add execute permission for the owner.
17. Numeric chmod
You will often see:
chmod 755 script.shNow you know where the numbers come from.
7 → rwx
5 → r-x
5 → r-xTherefore:
755
│││
││└── Others → r-x
│└─── Group → r-x
└──── Owner → rwxSo:
chmod 755 script.shproduces:
-rwxr-xr-x18. chown
What if we want to change ownership?
That’s where:
chowncomes in.
For example:
sudo chown alice config.yamlchanges the owner to:
aliceYou can also change owner and group:
sudo chown alice:developers config.yamlNow:
Owner → alice
Group → developers19. chgrp
You can change just the group:
sudo chgrp developers config.yamlSo:
chown → ownership
chgrp → group ownership
chmod → permissionsA simple memory trick:
chmod → WHAT can they do?
chown → WHO owns it?
chgrp → WHICH GROUP owns it?20. Why Do We Need sudo?
Now let’s talk about privileges.
Suppose you’re logged in as:
aliceand try:
cat /etc/shadowYou may receive:
Permission deniedBut:
sudo cat /etc/shadowmay work if Alice is authorized to use sudo for that command.
Conceptually:
Alice
↓
sudo
↓
Elevated privileges
↓
Commandsudo does not simply mean "become root forever."
It allows an authorized user to execute a command with elevated privileges according to the system’s sudo policy.
Does Alice need to be configured to use sudo?
Yes.
Suppose you create:
Alice
UID = 1001By default, that does not necessarily mean Alice can run:
sudo systemctl restart nginxLinux needs a sudo policy that authorizes Alice.
For example, on Ubuntu, an administrator might add Alice to the sudo group:
sudo usermod -aG sudo aliceThen Alice may be allowed to use sudo according to the system's sudo configuration.
Get Oshadhi Wickramasinghe’s stories in your inbox
Join Medium for free to get updates from this writer.
You can check the user’s groups:
groups aliceYou might see:
alice sudo developersHere:
alice
├── alice ← primary group
├── sudo ← can use sudo
└── developers ← project accessHowever, being in a sudo group is not the only possible configuration. sudo can be configured to allow particular users or groups to run particular commands.
ROOT
↓
A user/account with UID 0 and very high privileges
SUDO
↓
A mechanism that allows an authorized user
to run a command with another user's privileges,
commonly root.What If Alice Actually Becomes Root?
There is another 3 commands:
sudo -i
sudo suIf Alice knows the root password and is permitted to use su, she can switch to the root account.
Then:
whoamireturns:
rootNow she has a root shell:
root@server:~#rather than:
alice@server:~$Conceptually:
Alice
│
│ su or -i
▼
root shell
UID 0Now every command she launches from that shell normally starts with root credentials unless she deliberately changes identity/privileges.
1. sudo -i
This is the cleaner and more direct approach.
sudo -iThink of it as:
You are Alice
↓
sudo says: "Alice is allowed to elevate"
↓
Start an interactive login shell as root
↓
You are now rootBefore:
alice@server:~$After:
root@server:~#Check:
whoamiOutput:
rootAnd:
idwill show UID 0.
The -i means approximately:
Start a login-style shell with root’s environment.
So things such as root’s home directory and environment are set appropriately.
2. sudo su
This is slightly different.
There are actually two commands involved:
sudoand:
suRemember:
sudo → execute something with elevated privileges
su → switch to another userSo:
sudo sumeans:
Alice
↓
sudo
↓
Run the `su` command as root
↓
su switches to root
↓
Root shellYou can visualize it:
Alice
│
│ sudo
▼
root privileges
│
│ run "su"
▼
su switches user
│
▼
root shellYou’ll normally end up with:
root@server:~#| Command | Simple meaning | What happens |
| -------------- | -------------------------------------------- | ----------------------------- |
| `sudo command` | Run **one command** with elevated privileges | You stay as your normal user |
| `sudo -i` | Open a **root shell** | You become root in that shell |
| `sudo su` | Also open a **root shell**, but indirectly | `sudo` runs `su` |21. Why Not Always Use Root?
Imagine every application runs as:
rootNow imagine an application has a vulnerability.
An attacker manages to exploit it.
If the application is root:
Attacker
↓
Application vulnerability
↓
Root privileges
↓
Potentially huge system impactBut if the application runs as:
nginxwith only the permissions it needs:
Attacker
↓
Application vulnerability
↓
nginx user
↓
Limited permissionsThe potential damage is reduced.
This is the principle of:
Least privilege
Give a user/process only the permissions it actually needs.
22. This Is Extremely Important in DevOps
Consider Nginx.
You might have:
nginx process
↓
nginx user
↓
/var/www/htmlThe Nginx process doesn’t need unrestricted access to the entire server.
Similarly, a CI/CD application shouldn’t automatically need:
rootjust because it needs to deploy something.
And a Docker container doesn’t necessarily need unrestricted host privileges.
This leads to concepts we’ll study later:
Linux permissions
↓
Process users
↓
sudo
↓
Capabilities
↓
Docker security
↓
Kubernetes securityContext23. The Classic “Permission Denied” Incident
Imagine your application tries:
/opt/app/config.yamland gets:
Permission deniedDon’t immediately run:
chmod 777 config.yamlThat’s a common beginner mistake.
Instead investigate.
First:
whoamiThen:
idThen:
ls -l /opt/app/config.yamlMaybe you find:
-rw------- root root config.yamlThe application runs as:
appuserSo:
appuser
↓
tries to read
↓
config.yaml
↓
root:root
↓
rw-------
↓
DENIEDNow you understand why it failed.
The solution might be to change ownership/group or permissions appropriately — not blindly use 777.
24. Why chmod 777 Is Dangerous
You will often see people solve permission problems with:
chmod 777 fileThis means:
Owner → rwx
Group → rwx
Others → rwxEveryone gets everything allowed by the file type.
That may make the problem disappear:
Permission denied ❌
↓
chmod 777
↓
Permission denied ✅ fixedBut you’ve potentially created a security problem.
A better approach is:
Give the minimum permission required.
For example:
640means:
Owner → rw-
Group → r--
Others → ---Much safer when appropriate.
25. A Real DevOps Example
Imagine:
Application
↓
runs as appuser
↓
needs to read
↓
/opt/app/config.yamlYou inspect:
ls -l /opt/app/config.yamland see:
-rw-r----- root developers config.yamlNow check:
id appuserSuppose:
groups=appuser,developersThe application belongs to:
developersThe file gives the group:
r--Therefore:
appuser
↓
member of developers
↓
config.yaml
↓
group permission = r--
↓
READ ALLOWEDThat’s the kind of reasoning you want to develop.
26. Permissions Are Not Just About Files
Linux permissions apply to many filesystem objects.
For example:
Files
Directories
Device files
Sockets
Named pipesThis is why understanding permissions is fundamental to Linux administration.
27. Special Permissions
Once you’ve mastered normal permissions, Linux provides additional mechanisms.
Normally, Linux permissions look like:
rwx rwx rwx
│ │ │
│ │ └── Others
│ └────── Group
└────────── OwnerBut Linux also has three special permissions:
SUID
SGID
Sticky BitThey are used for different purposes:
SUID → Run a program with the file owner's privileges
SGID → Run a program with the file group's privileges
OR make new files inherit a directory's group
Sticky Bit → Restrict who can delete files in a shared directoryLet’s understand each.
1. SUID
SUID means:
Set User ID
The easiest way to understand it is with a real Linux command:
passwdWhen you need to change the password, you need to use passwd command.
When you change your password:
passwdthe command needs to modify files that normal users cannot directly modify, such as the system’s password-related files.
But you are not root.
So how can passwd do this?
One mechanism Linux can use is SUID.
The executable may have permissions similar to:
-rwsr-xr-xNotice this:
-rwsr-xr-x
^
sNormally the owner’s execute permission is:
rwxWith SUID, the x position can become:
sSo:
rwxbecomes:
rwsThis means:
When an authorized user executes this program, the process can run with the file owner’s effective privileges.
For example:
passwd executable
│
│ owned by root
▼
root
│
│ SUID
▼
User runs passwd
│
▼
Process gets root effective privileges
│
▼
Can perform the privileged operationImportant
SUID does not mean:
“The user becomes root.”
It means the process executing that particular SUID program gets the executable file owner’s effective privilege.
This is why SUID programs must be carefully controlled.
2. SGID
SGID means:
Set Group ID
SGID has two important behaviors depending on whether it is applied to a file or a directory.
SGID on an executable file
Similar to SUID, an executable with SGID can run with the file group’s effective privileges.
For example:
-rwxr-sr-x
^
sThe s appears in the group execute position.
Conceptually:
Executable
│
│ owned by
▼
developers group
│
│ SGID
▼
Process runs with
developers group privilegesSGID on a directory
This is much more useful in everyday DevOps/Linux administration.
Suppose we have:
/opt/projectand we want everyone working on the project to share the same group.
We can have:
root:developersand set SGID on the directory.
The directory might look like:
drwxrwsr-x
^
sNow files created inside the directory can inherit the directory’s group.
For example:
/opt/project
│
├── app.py
├── config.yaml
└── logs.txtDirectory:
root:developersNew files can inherit:
developersas their group.
This is very useful for shared project directories.
Think:
SGID on directory
↓
New files/directories
↓
Inherit the directory's group3. Sticky Bit
drwxrwxrwtThis is commonly seen on:
/tmpLook at the final character:
drwxrwxrwt
^
tThat t means:
Sticky Bit
But what does it actually do?
Imagine /tmp is a shared directory.
Many users need to create files there:
/tmp
│
├── alice-file
├── bob-file
├── charlie-file
└── application-fileThe directory needs to allow users to create files.
So it might have:
rwxfor everyone.
But there’s a problem.
If everyone has write permission to the directory, could Bob delete Alice’s file?
Without the sticky bit, potentially yes, depending on the permissions and ownership involved.
The sticky bit changes this behavior.
With:
drwxrwxrwtusers can generally delete or rename entries in the shared directory only when they have the appropriate ownership/privilege, typically because they own the file, own the directory, or are root.
So:
/tmp
│
├── Alice's file
├── Bob's file
└── Charlie's fileBob:
Can create his own file ✅
Can delete his own file ✅
Can normally delete Alice's ❌That’s why the sticky bit is useful for shared directories such as /tmp.
28. ACLs — When Normal Permissions Aren’t Enough
Normal Linux permissions give us three permission categories:
Owner
Group
OthersFor example, if a file is:
-rw-r----- alice developers config.yamlThe permissions are:
Alice → read + write
Developers group → read
Others → no accessNow suppose Bob needs read access to config.yaml.
If Bob should have the same access as the developers group, we can simply add Bob to the developers group:
sudo usermod -aG developers bobHowever, what if Bob needs access to this particular file only, and we don’t want to give him access to every file that the developers group can access?
That’s where ACLs — Access Control Lists come in.
ACLs allow us to provide additional, more granular permissions to specific users or groups without changing the file’s primary owner or group.
For example:
setfacl -m u:bob:r-- config.yamlThis gives Bob read access specifically to config.yaml.
We can inspect the ACL with:
getfacl config.yamlSo the general idea is:
Same access as the group?
↓
Add the user to the group
Different/specific access?
↓
Use ACLACLs are useful when normal Owner / Group / Others permissions are not granular enough.
29. Linux Capabilities
There’s another interesting concept.
Traditional Linux thinking often looks like:
Normal user
↓
RootBut modern Linux can divide many privileged operations into capabilities.
For example:
CAP_NET_ADMIN
CAP_NET_BIND_SERVICE
CAP_SYS_ADMINThis allows a process to have specific privileged capabilities without giving it every traditional root privilege.
This becomes extremely important when you study:
Docker
Kubernetes
Containers
SecurityContext
Pod security30. The Complete Mental Model
Now let’s put everything together.
USER
│
▼
UID + Groups
│
▼
PROCESS
│
│ access request
▼
FILE
│
┌─────────┴─────────┐
▼ ▼
Ownership Permissions
│ │
┌──────┴──────┐ ┌─────┴─────┐
▼ ▼ ▼ ▼ ▼
Owner Group r w x
│ │
└──────┬──────┘
▼
Linux Kernel
│
Permission Check
│
┌─────┴─────┐
▼ ▼
ALLOW DENYAnd when elevated privileges are needed:
User
↓
sudo
↓
Elevated privileges
↓
Command31. The Commands You Should Know
At this stage, focus on these:
Who am I?
whoamiWhat is my UID/GID/groups?
idWhat groups am I in?
groupsWho owns this file?
ls -l fileDetailed file information
stat fileChange permissions
chmodChange owner
chownChange group
chgrpRun with elevated privileges
sudoInspect ACLs
getfacl32. The Troubleshooting Flow
When you see:
Permission denieddon’t immediately use:
chmod 777Instead:
Permission denied
↓
Who is running the process?
↓
whoami / ps / id
↓
What file/directory is being accessed?
↓
ls -l / stat
↓
Who owns it?
↓
What group owns it?
↓
What permissions exist?
↓
Does the process belong to that group?
↓
Is there an ACL?
↓
Is sudo/elevation actually required?
↓
Fix the minimum required permissionThis is a much better DevOps mindset.
Final Mental Model
The entire topic can be reduced to one question:
Who is trying to do what to which resource?
For example:
WHO?
↓
appuser
↓
WHAT?
↓
read
↓
WHICH RESOURCE?
↓
/opt/app/config.yaml
↓
WHO OWNS IT?
↓
root:developers
↓
WHAT PERMISSIONS?
↓
-rw-r-----
↓
IS appuser IN developers?
↓
YES
↓
READ ALLOWEDAnd that’s the heart of Linux permissions.
You don’t need to memorize:
chmod 755
chmod 644
chown
chgrp
sudoas isolated commands.
Instead, understand the relationship:
Linux Security Model
User
↓
UID
↓
Groups
↓
Process
↓
Access request
↓
File/Directory
↓
Owner + Group
↓
Permissions
↓
Kernel
↓
ALLOW / DENY






