DEV Community

Cover image for Today I Taught Linux File Permissions - And Alice Couldn't Read the Salary File
Navas Herbert
Navas Herbert

Posted on

Today I Taught Linux File Permissions - And Alice Couldn't Read the Salary File

 I opened today's session with a question.

"Imagine you leave your laptop open in a coffee shop in Westlands. What stops a stranger from reading your files?"

Silence. A few answers. Then I said: "On Linux - the answer is permissions. Every single file on this server has a set of rules that says who can touch it. Today we are going to learn exactly how that works, live on a real server."

New cohort. Fresh faces. Some had never touched a terminal before. By the end of two hours, they had created real user accounts, organised them into groups, locked down files, and proved - by trying to break in as a different user -that their permissions actually worked.

Here's how it went.


First: Getting On a Real Server

No local files. No virtual machines. We SSH'd into a live Ubuntu server.

ssh root@159.x.x.x
Enter fullscreen mode Exit fullscreen mode

That first SSH fingerprint warning - the one that looks scary - causes a pause in every cohort:

The authenticity of host '159.x.x.x' can't be established.
Are you sure you want to continue connecting (yes/no)?
Enter fullscreen mode Exit fullscreen mode

I explained: "Linux is asking - I've never seen this server before, do you trust it? We say yes." After that, the prompt changed:

Welcome to Ubuntu 22.04 LTS
root@server:~#
Enter fullscreen mode Exit fullscreen mode

That # symbol. I made sure everyone understood what it meant - root, the most powerful user on the system. The whole reason permissions exist is to protect files from that kind of power being used carelessly.


The Mental Model: Three Questions Linux Always Asks

Before any commands, I drew three questions on the board:

  1. WHO owns this file? - the Owner
  2. What GROUP is it in? -the Group, a shared team of users
  3. Is everyone else allowed? - Others

And for each of those three, Linux grants up to three abilities:

Symbol Name On a file On a directory
r read Open and read it Run ls inside
w write Edit or delete it Create/delete files inside
x execute Run it as a program cd into it
- none Denied Denied

Then the 10-character string that wraps all of this together:

- r w x   r - x   r - -
  ─────   ─────   ─────
  owner   group   others
└── file type: - = file, d = directory
Enter fullscreen mode Exit fullscreen mode

Five minutes of theory. Then hands-on immediately.


Creating Real Users: Alice and Bob

We created two users directly on the server - alice and bob. These would be our test subjects for the whole session.

adduser alice
Enter fullscreen mode Exit fullscreen mode

Linux walked through everything interactively - set a password, created a home folder at /home/alice, created a group with the same name. I made the point: "Notice Linux did several things at once. It created the user, created a private group for her, and gave her a home folder that belongs to her alone."

id alice
Enter fullscreen mode Exit fullscreen mode
uid=1001(alice) gid=1001(alice) groups=1001(alice)
Enter fullscreen mode Exit fullscreen mode

Three ways to verify a user exists - id, checking /etc/passwd, and listing /home/. I showed all three so students knew different tools rather than memorising one path.


Groups: The Company Department Analogy

The real-world analogy I use every time: a company. Everyone in the Development team can read the source code. Everyone in Finance can read payroll files. You don't set permissions for every individual - you create a group and add people to it.

groupadd devteam
usermod -aG devteam alice
usermod -aG devteam bob
groups alice
Enter fullscreen mode Exit fullscreen mode
alice : alice devteam
Enter fullscreen mode Exit fullscreen mode

The -aG warning always needs emphasis. Use -G without -a and you silently remove all the user's existing groups. One missing letter, broken access. I've seen that mistake cause real problems in production environments. Worth saying twice in class.


Reading Permissions: The ls -l Moment

We created a /project folder with three files:

mkdir /project
echo 'This is the main app code' > /project/app.py
echo 'Top secret salary data'    > /project/salaries.txt
echo 'Public readme'             > /project/README.txt
ls -l /project/
Enter fullscreen mode Exit fullscreen mode
-rw-r--r-- 1 root root 26 Jan  1 10:00 app.py
-rw-r--r-- 1 root root 24 Jan  1 10:00 README.txt
-rw-r--r-- 1 root root 23 Jan  1 10:00 salaries.txt
Enter fullscreen mode Exit fullscreen mode

All three files showing -rw-r--r--. I pointed at salaries.txt and said: "Right now, any user on this server can read the salary file. That's a problem. Let's fix it."


chmod: Locking Things Down

Two ways to use chmod - numbers (fast) and symbols (readable). I teach both.

The number system: each permission has a value. r=4, w=2, x=1. Add them up for each group. Owner, group, others — three digits.

The numbers worth memorising:

Number String Use
777 rwxrwxrwx Everyone everything — dangerous
755 rwxr-xr-x Programs, public directories
644 rw-r--r-- Normal files
640 rw-r----- Team files — group reads, others locked
600 rw------- Private (SSH keys, credentials)

We set them live:

chmod 600 /project/salaries.txt
chmod 640 /project/app.py
chmod 644 /project/README.txt
ls -l /project/
Enter fullscreen mode Exit fullscreen mode
-rw-r--r-- 1 root root 24 Jan  1 10:00 README.txt
-rw-r----- 1 root root 26 Jan  1 10:00 app.py
-rw------- 1 root root 23 Jan  1 10:00 salaries.txt
Enter fullscreen mode Exit fullscreen mode

The Moment That Made the Session

Then we switched to alice and tried to read the salary file:

su - alice
cat /project/salaries.txt
Enter fullscreen mode Exit fullscreen mode
cat: /project/salaries.txt: Permission denied
Enter fullscreen mode Exit fullscreen mode

The room reacted. A few people laughed. One student said "it actually works."

That's the moment I wait for every cohort. Not because it's complicated — it isn't. But because seeing a real system refuse access, because of rules they set, makes it concrete in a way no amount of theory can. They didn't just learn about permissions. They used them.


chown: Handing Ownership to the Right Person

Permissions control what can be done. Ownership controls who the rules apply to. chown transfers ownership:

chown alice:devteam /project/app.py
ls -l /project/app.py
Enter fullscreen mode Exit fullscreen mode
-rwxr----- 1 alice devteam 26 Jan  1 10:00 app.py
Enter fullscreen mode Exit fullscreen mode

Now alice owns the file and devteam is the group. Because bob is in devteam, the group permission (r--) applies to him - he can read, but not write.

We proved it:

su - bob
cat /project/app.py          # works - group has r
echo 'bob was here' >> /project/app.py  # denied - group has no w
Enter fullscreen mode Exit fullscreen mode
This is the main app code
bash: /project/app.py: Permission denied
Enter fullscreen mode Exit fullscreen mode

"Bob can read the code but can't change it. That's how a real team works."


What I Noticed Teaching This Session

1. The SSH fingerprint warning catches everyone. It looks dangerous. A quick calm explanation - "Linux is asking if you trust this server" - is all it takes. Don't skip it.

2. The Permission denied moment is worth engineering. I could have just explained that permissions work. Instead I made them set up a file, lock it down, then try to break in as another user. Seeing their own rules enforced is the most memorable minute of the session.

3. The -aG warning needs to be said out loud, twice. Silent data loss - user loses all group memberships with one wrong flag - is the kind of mistake that causes real incidents. Beginners need to hear that this is serious before they learn the command, not after.

4. New cohort energy is different. These students had never touched a terminal before today. By the end they were switching between user accounts, testing access, reading permission strings without help. That progression in two hours is why I love this job.

Try It Yourself

You don't need a paid server. Spin up a free Ubuntu instance on:

Then run through the sequence: create two users, a group, three files with different permissions, and prove it works by switching between accounts. The Permission denied message will feel like a win, not an error.


I'm a data trainer in Nairobi running a full data programme -
Python foundations → Data Science or Data Engineering specialisations.
I write daily about what I taught, what worked, and what surprised me in the classroom.
Follow along or drop your questions in the comments.

Top comments (0)