Skip to main content
Linux beginner Lesson 3 of 5

Linux Users, Groups & Permissions

Learn the Unix permission model: ownership, groups, chmod/chown, and practical patterns for running services safely.

In DevOps, permissions are the difference between:

  • a service that starts and writes logs correctly
  • and a service that crashes silently (or can’t read configs / can’t access volumes)

This tutorial focuses on the practical mental model and the most common commands.

Learning outcomes

By the end, you’ll be able to:

  • interpret ls -l output
  • use chown and chgrp
  • use chmod (symbolic + numeric)
  • avoid common permission pitfalls for services and deployment artifacts

Ownership and groups (who “owns” the file)

Every file/directory has:

  • owner (user)
  • group
  • permission bits

Check it:

ls -l /etc/nginx/nginx.conf
# -rw-r--r-- 1 root root  1234 Jan 01 00:00 nginx.conf

Interpretation:

  • root root → owner and group
  • -rw-r--r-- → permissions

Permission bits: what each triplet means

- rwx r-x r--

  • owner: rw-
  • group: r-x
  • others: r--

Where:

  • r = read
  • w = write
  • x = execute/search (for directories)

chmod: change permissions

Symbolic mode (human-friendly)

# add read permission for group
chmod g+r file.txt

# remove write permission for others
chmod o-w file.txt

# set exact permissions (symbolic)
chmod u=rwx,g=rx,o=r file.txt

Numeric mode (common in scripts)

Numeric mapping:

  • 4 = read
  • 2 = write
  • 1 = execute

So:

  • 7 = rwx
  • 5 = r-x
  • 4 = r—

Examples:

# rwxr-xr-x = 755
chmod 755 /usr/local/bin/myapp

# rw-r--r-- = 644
chmod 644 ./config.yml

chown / chgrp: change owner and group

# change owner only
sudo chown myuser: /var/log/myapp

# change owner and group
sudo chown myuser:mygroup /var/log/myapp

# change group recursively
sudo chgrp -R mygroup /srv/myapp

Practical patterns for running services safely

1) Create a dedicated user

Instead of running as root, create an app user and chown the directories it needs.

2) Use restrictive defaults for secrets

  • config files containing credentials: 640 or 600
  • directories for app logs: 750

3) Prefer group-based sharing

If multiple processes need shared read access:

  • set a common group
  • set group read perms

Example:

# shared directory
sudo chown -R appuser:appgroup /srv/myapp
sudo chmod -R g+rX /srv/myapp

Special bits (when you must share safely)

Sticky bit (t = on directory)

Useful for world-writable temp dirs like /tmp.

  • non-owners can’t delete each other’s files

Check:

ls -ld /tmp
# drwxrwxrwt

setuid/setgid

Advanced but occasionally needed (rare in modern service deployments).

Troubleshooting checklist

If your service can’t read/write:

  1. verify the process user/group
    ps aux | grep myapp
  2. verify permissions on the target paths
    ls -l /path/to/config /path/to/logs
  3. confirm group membership and ownership
  4. re-check mounted volumes and deployment steps

Next steps

Continue with:

  • Linux networking fundamentals
  • shell scripting patterns for repeatable ops
  • processes + systemd logs

Frequently Asked Questions

Why do services fail after changing file permissions?
Because the service runs under a specific user/group; read/write/execute bits (and sometimes SELinux/AppArmor) must match what the process needs for configs, logs, and mounted volumes.
What’s the purpose of the setuid/setgid/sticky bits?
They modify how permissions behave. setuid/setgid run executables with the file’s owner/group; sticky prevents non-owners from deleting others’ files in a shared directory.