Sitemap

Linux Users, Groups, Permissions & Privileges — Understanding Who Can Do What

15 min readSep 2, 2026

--

When I started working with Linux, I kept seeing commands like:

ls -l
chmod
chown
sudo
whoami
id
groups

I 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 DENY

1. What Is a Linux User?

A user is an identity recognized by Linux.

For example:

alice
bob
devops
ubuntu
root

When you log into a Linux server:

ssh alice@server

Linux identifies you as:

alice

But 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 0

This is important.

Linux ultimately cares about the UID, not simply the username.

2. The Root User

You’ve probably heard of:

root

Root is the most privileged traditional Linux user.

The root user normally has:

UID = 0

This is why you’ll often see:

id root

return 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/directory

A normal user might receive:

Permission denied

while 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/passwd

You can inspect it:

cat /etc/passwd

You 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/bash

Each line describes a user account.

For example:

alice:x:1001:1001:Alice:/home/alice:/bin/bash

contains information such as:

username
UID
GID
home directory
login shell

Modern 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:

developers

Then:

Alice ──┐
Bob ──┼──→ developers
John ──┤
Sara ──┘

Now you can give permissions to the group.

For example:

/opt/application/

could belong to:

root:developers

and 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 2001

You can see your groups with:

groups

Or:

id

For 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 group

6. Primary and Supplementary Groups

A Linux user can belong to multiple groups.

For example:

Alice
│
├── Primary group → alice
│
├── Supplementary → developers
│
├── Supplementary → docker
│
└── Supplementary → monitoring

Check with:

id alice

This becomes very useful in DevOps.

For example, a user might belong to:

docker

which allows them to interact with the Docker daemon according to the system’s configuration.

7. Now Let’s Look at a File

Run:

ls -l

You might see:

-rw-r----- 1 alice developers 1024 Aug 31 10:00 config.yaml

This line contains a lot of information.

Let’s focus on:

-rw-r-----

and:

alice developers

The ownership is:

Owner → alice
Group → developers

The 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 = execute

They can be represented numerically:

r = 4
w = 2
x = 1

Why?

Because:

4 + 2 + 1 = 7

So:

rwx = 7
rw- = 6
r-x = 5
r-- = 4
-wx = 3
-w- = 2
--x = 1
--- = 0

We’ll use this when we learn chmod.

9. User, Group, Others

Linux divides permission checks into three categories:

USER
GROUP
OTHERS

For example:

-rwxr-xr--

Break it into:

- | rwx | r-x | r--
│ │ │
│ │ └── Others
│ └──────── Group
└────────────── Owner

So:

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

rwx

The owner can:

read
write
execute

Group

r-x

The group can:

read
execute

but cannot:

write

Others

r--

Everyone else can:

read

but cannot:

write
execute

11. 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 link

So:

-rwxr-xr--

means:

-       → regular file
rwx → owner permissions
r-x → group permissions
r-- → others permissions

While:

drwxr-xr-x

means:

d       → directory
rwx → owner
r-x → group
r-x → others

12. Directory Permissions Are Different

This is where many beginners get confused.

For a file:

r → read contents
w → modify contents
x → execute

But for a directory, the meaning changes.

Directory r

Allows you to list directory entries.

ls directory

Directory 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 /data

requires execute permission on the directory.

So:

Directory:

r → list
w → create/delete/rename entries
x → enter/traverse

This is extremely important.

13. Here’s a Real Example

Suppose:

/data

has:

drwxr-x---

And:

owner = root
group = developers

Then:

root
↓
rwx

developers
↓
r-x

others
↓
---

A developer can:

list files        ✅
enter directory ✅
create files ❌
delete files ❌

Why?

Because the group has:

r-x

but not:

w

14. How Does Linux Actually Decide?

Now we’re getting to the most important part.

Suppose:

Alice

tries to read:

ls /opt/app/config.yaml

Linux 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:

ls

Linux needs to execute the ls program.

So Linux creates a process:

Alice (user)
│
│ runs
▼
ls
│
▼
Process
PID = 1234

So:

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 = 1001

Alice runs:

ls

Linux creates:

Process
PID = 1234
UID = 1001

So we can think of it as:

Alice
UID 1001
│
│ starts
▼
ls process
PID 1234
UID 1001

The process doesn’t simply carry the word "alice" around.

The kernel uses credentials such as:

UID
GID
Supplementary groups

to 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 / DENY

15. An Important Rule

Linux doesn’t normally combine:

owner permissions
+
group permissions
+
others permissions

Instead, the permission class that applies to the process is selected.

For example:

-rw-r-----
alice developers

If 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:

chmod

chmod means:

change mode

For example:

chmod u+x script.sh

means:

u → user/owner
+ → add
x → execute

So:

Add execute permission for the owner.

17. Numeric chmod

You will often see:

chmod 755 script.sh

Now you know where the numbers come from.

7 → rwx
5 → r-x
5 → r-x

Therefore:

755
│││
││└── Others → r-x
│└─── Group → r-x
└──── Owner → rwx

So:

chmod 755 script.sh

produces:

-rwxr-xr-x

18. chown

What if we want to change ownership?

That’s where:

chown

comes in.

For example:

sudo chown alice config.yaml

changes the owner to:

alice

You can also change owner and group:

sudo chown alice:developers config.yaml

Now:

Owner → alice
Group → developers

19. chgrp

You can change just the group:

sudo chgrp developers config.yaml

So:

chown → ownership
chgrp → group ownership
chmod → permissions

A 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:

alice

and try:

cat /etc/shadow

You may receive:

Permission denied

But:

sudo cat /etc/shadow

may work if Alice is authorized to use sudo for that command.

Conceptually:

Alice
↓
sudo
↓
Elevated privileges
↓
Command

sudo 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 = 1001

By default, that does not necessarily mean Alice can run:

sudo systemctl restart nginx

Linux needs a sudo policy that authorizes Alice.

For example, on Ubuntu, an administrator might add Alice to the sudo group:

sudo usermod -aG sudo alice

Then 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 alice

You might see:

alice sudo developers

Here:

alice
├── alice ← primary group
├── sudo ← can use sudo
└── developers ← project access

However, 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 su

If Alice knows the root password and is permitted to use su, she can switch to the root account.

Then:

whoami

returns:

root

Now she has a root shell:

root@server:~#

rather than:

alice@server:~$

Conceptually:

Alice
│
│ su or -i
▼
root shell
UID 0

Now 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 -i

Think of it as:

You are Alice
↓
sudo says: "Alice is allowed to elevate"
↓
Start an interactive login shell as root
↓
You are now root

Before:

alice@server:~$

After:

root@server:~#

Check:

whoami

Output:

root

And:

id

will 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:

sudo

and:

su

Remember:

sudo → execute something with elevated privileges

su → switch to another user

So:

sudo su

means:

Alice
↓
sudo
↓
Run the `su` command as root
↓
su switches to root
↓
Root shell

You can visualize it:

Alice
│
│ sudo
▼
root privileges
│
│ run "su"
▼
su switches user
│
▼
root shell

You’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:

root

Now 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 impact

But if the application runs as:

nginx

with only the permissions it needs:

Attacker
↓
Application vulnerability
↓
nginx user
↓
Limited permissions

The 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/html

The Nginx process doesn’t need unrestricted access to the entire server.

Similarly, a CI/CD application shouldn’t automatically need:

root

just 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 securityContext

23. The Classic “Permission Denied” Incident

Imagine your application tries:

/opt/app/config.yaml

and gets:

Permission denied

Don’t immediately run:

chmod 777 config.yaml

That’s a common beginner mistake.

Instead investigate.

First:

whoami

Then:

id

Then:

ls -l /opt/app/config.yaml

Maybe you find:

-rw------- root root config.yaml

The application runs as:

appuser

So:

appuser
↓
tries to read
↓
config.yaml
↓
root:root
↓
rw-------
↓
DENIED

Now 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 file

This means:

Owner  → rwx
Group → rwx
Others → rwx

Everyone gets everything allowed by the file type.

That may make the problem disappear:

Permission denied ❌
↓
chmod 777
↓
Permission denied ✅ fixed

But you’ve potentially created a security problem.

A better approach is:

Give the minimum permission required.

For example:

640

means:

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.yaml

You inspect:

ls -l /opt/app/config.yaml

and see:

-rw-r----- root developers config.yaml

Now check:

id appuser

Suppose:

groups=appuser,developers

The application belongs to:

developers

The file gives the group:

r--

Therefore:

appuser
↓
member of developers
↓
config.yaml
↓
group permission = r--
↓
READ ALLOWED

That’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 pipes

This 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
└────────── Owner

But Linux also has three special permissions:

SUID
SGID
Sticky Bit

They 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 directory

Let’s understand each.

1. SUID

SUID means:

Set User ID

The easiest way to understand it is with a real Linux command:

passwd

When you need to change the password, you need to use passwd command.

When you change your password:

passwd

the 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-x

Notice this:

-rwsr-xr-x
^
s

Normally the owner’s execute permission is:

rwx

With SUID, the x position can become:

s

So:

rwx

becomes:

rws

This 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 operation

Important

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
^
s

The s appears in the group execute position.

Conceptually:

Executable
│
│ owned by
▼
developers group
│
│ SGID
▼
Process runs with
developers group privileges

SGID on a directory

This is much more useful in everyday DevOps/Linux administration.

Suppose we have:

/opt/project

and we want everyone working on the project to share the same group.

We can have:

root:developers

and set SGID on the directory.

The directory might look like:

drwxrwsr-x
^
s

Now files created inside the directory can inherit the directory’s group.

For example:

/opt/project
│
├── app.py
├── config.yaml
└── logs.txt

Directory:

root:developers

New files can inherit:

developers

as their group.

This is very useful for shared project directories.

Think:

SGID on directory
↓
New files/directories
↓
Inherit the directory's group

3. Sticky Bit

drwxrwxrwt

This is commonly seen on:

/tmp

Look at the final character:

drwxrwxrwt
^
t

That 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-file

The directory needs to allow users to create files.

So it might have:

rwx

for 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:

drwxrwxrwt

users 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 file

Bob:

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
Others

For example, if a file is:

-rw-r----- alice developers config.yaml

The permissions are:

Alice              → read + write
Developers group → read
Others → no access

Now 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 bob

However, 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.yaml

This gives Bob read access specifically to config.yaml.

We can inspect the ACL with:

getfacl config.yaml

So the general idea is:

Same access as the group?
↓
Add the user to the group


Different/specific access?
↓
Use ACL

ACLs 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
↓
Root

But modern Linux can divide many privileged operations into capabilities.

For example:

CAP_NET_ADMIN
CAP_NET_BIND_SERVICE
CAP_SYS_ADMIN

This 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 security

30. 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 DENY

And when elevated privileges are needed:

User
↓
sudo
↓
Elevated privileges
↓
Command

31. The Commands You Should Know

At this stage, focus on these:

Who am I?

whoami

What is my UID/GID/groups?

id

What groups am I in?

groups

Who owns this file?

ls -l file

Detailed file information

stat file

Change permissions

chmod

Change owner

chown

Change group

chgrp

Run with elevated privileges

sudo

Inspect ACLs

getfacl

32. The Troubleshooting Flow

When you see:

Permission denied

don’t immediately use:

chmod 777

Instead:

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 permission

This 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 ALLOWED

And that’s the heart of Linux permissions.

You don’t need to memorize:

chmod 755
chmod 644
chown
chgrp
sudo

as isolated commands.

Instead, understand the relationship:

Linux Security Model

User
↓
UID
↓
Groups
↓
Process
↓
Access request
↓
File/Directory
↓
Owner + Group
↓
Permissions
↓
Kernel
↓
ALLOW / DENY
Press enter or click to view image in full size

--

--

Oshadhi Wickramasinghe
Oshadhi Wickramasinghe

Written by Oshadhi Wickramasinghe

Writing about DevOps, AWS, Kubernetes, Terraform, GitOps, CI/CD, monitoring, automation, and lessons from production environments.