Users, Groups, and Permissions

Introduction

Every file on Linux has an owner, a group, and permission bits for user/group/others. Misconfigured permissions cause Permission denied during deploys and security incidents when everything is 777. This chapter reads ls -l output and fixes access with chmod and chown.

Prerequisites

Users and Groups

bash
# Current user
whoami
 
# User id, primary group, all groups
id
 
# Switch user (needs password)
su - anotheruser
 
# Root shell (use carefully)
sudo -i

System accounts live in /etc/passwd; groups in /etc/group. You rarely edit those files by hand—use adduser on servers.

Add a deployment user (example):

bash
# Interactive user creation on Ubuntu
sudo adduser deploy
 
# Add to sudo group if admins required
sudo usermod -aG sudo deploy

Run apps as a dedicated non-root user in production—not as root.

Read ls -l Permission String

Example line:

text
-rwxr-xr-- 1 deploy deploy 4096 May 20 10:00 app.jar
FieldMeaning
-File type (- file, d directory, l symlink)
rwxOwner permissions
r-xGroup permissions
r--Others permissions
deploy deployOwner user and group
app.jarName

Letters: r read, w write, x execute. For directories, x means you may cd into it.

chmod: Symbolic and Numeric

Symbolic:

bash
# Add execute for owner
chmod u+x script.sh
 
# Read/write for owner, read for group/others
chmod u=rw,go=r config.properties

Numeric (common in tutorials and deploy docs):

ModeMeaningTypical use
755rwxr-xr-xDirectories, executable scripts
644rw-r--r--Regular files, configs
600rw-------Secrets (SSH keys, .env)
700rwx------Private directories (~/.ssh)
bash
# Make script executable
chmod 755 deploy.sh
 
# Private key file
chmod 600 ~/.ssh/id_ed25519

Warning

chmod -R 777 fixes permission errors temporarily and opens files to everyone. Never use 777 on servers—find the real owner/group issue instead.

chown and chgrp

Change owner (root or sudo):

bash
# Change owner and group
sudo chown deploy:deploy /opt/myapp/app.jar
 
# Recursive for directory tree
sudo chown -R deploy:deploy /opt/myapp
bash
# Change group only
sudo chgrp www-data /var/www/html

Nginx or Apache often need www-data group on web roots; Java apps often run as deploy or a service user.

umask: Default Permissions for New Files

bash
# Show current umask
umask

Default 022 on many systems yields 755 for new directories and 644 for new files (subtract from 777). Developers rarely change umask; know it exists when new files look “too open” or “too closed”.

Special Permissions (Awareness)

BitNameOne-line idea
setuids on user xRun as file owner (e.g. passwd)
setgids on group xRun as file group
stickyt on dir xOnly owner deletes own files in /tmp
bash
# Sticky bit visible on /tmp
ls -ld /tmp

You will not set these often; recognize them in ls -l.

Deploy Scenario: Spring Boot JAR

bash
# App owned by deploy user
sudo mkdir -p /opt/myapp
sudo chown deploy:deploy /opt/myapp
 
# JAR readable, not world-writable
sudo cp app.jar /opt/myapp/
sudo chown deploy:deploy /opt/myapp/app.jar
chmod 644 /opt/myapp/app.jar

Logs directory writable by app user only:

bash
sudo mkdir -p /opt/myapp/logs
sudo chown deploy:deploy /opt/myapp/logs
chmod 755 /opt/myapp/logs

Mini Example: Fix Script Not Executable

bash
# Script fails with Permission denied
./run.sh
 
# Add execute bit
chmod +x run.sh
./run.sh

FAQ

Why Permission denied on a script I own?

Missing x bit, or filesystem mounted noexec. Run ls -l script.sh and mount | grep mountpoint.

Should I run Java as root?

No—use a service user and systemd (covered in a later chapter).

sudo chmod vs chmod?

Changing another user’s files requires root/sudo. Your own files: plain chmod.

Groups and Docker?

Docker daemon often requires docker group membership—adds privileges; understand security trade-offs.

What comes next?

Shell and Bash basics.