Understanding Linux Groups and Group Permissions

Linux groups are named collections of user accounts that share a common set of permissions. Every file has an associated group, and the group permission bits control what members of that group can do with the file. Groups enable controlled sharing — a file can be readable and writable by specific users (via group membership) without being accessible to everyone. Each user has one primary group and can belong to multiple supplementary groups, each granting access to different resources.

The Middle Ground of Linux Permissions

The Linux permission system gives every file three sets of access controls: one for the file’s owner, one for a specific group, and one for everyone else. The owner and “everyone else” categories are self-explanatory — but groups are where the real power of Linux’s multi-user access control lives.

Groups solve a fundamental problem in multi-user systems: how do you share access to files and resources with a specific set of users, without making those resources available to everyone? The owner-only model is too restrictive — if only the owner can write a file, collaboration requires constant permission changes or copying. The world-readable model is too permissive — making files accessible to all users destroys privacy and security. Groups provide the middle ground: a named, managed set of users who share access to specific resources.

Every practical Linux system uses groups extensively. The sudo group controls who can run administrative commands. The docker group controls who can manage containers. The www-data group controls which processes can read web server files. The audio and video groups control hardware access. Custom groups like developers or accounting organize teams around shared project resources.

This article explains what groups are at a technical level, how primary and supplementary groups work, how group permissions integrate with the file permission system, how to create and manage groups, and the practical patterns for using groups to create sensible, secure multi-user environments.

What Groups Are: The Technical Foundation

Groups as Identity Collections

A group in Linux is, at its simplest, a named list of user accounts identified by a numeric Group ID (GID). When a user belongs to a group, they inherit that group’s access to any files where the group permission bits apply.

Groups are stored in /etc/group. Each line defines one group:

$ cat /etc/group
root:x:0:
daemon:x:1:
...
sudo:x:27:sarah,alice,bob
audio:x:29:sarah,pulse
video:x:44:sarah
docker:x:998:sarah,alice
developers:x:1001:sarah,alice,bob,carol
sarah:x:1000:

Each colon-separated line contains:

  • Group name — the human-readable identifier (developers)
  • Group password — x means the password is in /etc/gshadow (rarely used; group passwords are an obscure feature)
  • GID — the numeric Group ID (1001)
  • Member list — comma-separated usernames of group members (sarah,alice,bob,carol)

The GID is what the kernel actually uses — just as UIDs identify users to the kernel, GIDs identify groups. The human-readable names exist for convenience.

The /etc/gshadow File

Just as /etc/shadow stores hashed user passwords, /etc/gshadow stores group passwords and administrative information. In practice, group passwords are almost never used on modern systems, but the file exists for completeness.

$ sudo cat /etc/gshadow | grep developers
developers:!::sarah,alice,bob,carol

The ! indicates no group password is set.

Primary vs. Supplementary Groups

Every user has exactly one primary group and zero or more supplementary groups. These serve different purposes.

Primary Group

The primary group is the group associated with a user’s login session. Its key role is determining the default group ownership of new files:

When you create a new file or directory, it is automatically owned by your current primary group (unless the directory has the SetGID bit set, which overrides this — covered later).

$ id
uid=1000(sarah) gid=1000(sarah) groups=1000(sarah),27(sudo),1001(developers),998(docker)

In this id output:

  • uid=1000(sarah) — user ID and username
  • gid=1000(sarah) — primary group ID and name
  • groups=... — all groups, including the primary

Sarah’s primary group is sarah (GID 1000) — her personal group. This is the standard Ubuntu/Debian pattern: each user gets a private group with the same name, ensuring that files created by default are not automatically shared with anyone.

On Fedora and RHEL-based systems, the same pattern applies by default (USERGROUPS_ENAB in /etc/login.defs controls this behavior).

Setting the primary group during user creation:

$ sudo useradd -g developers alice    # Primary group is developers

Changing an existing user’s primary group:

$ sudo usermod -g developers alice

After this change, files Alice creates will be owned by the developers group by default — immediately shareable with all developers without any permission changes.

Supplementary Groups

Supplementary groups are all the other groups a user belongs to beyond their primary group. They grant access to resources without affecting default file ownership.

When Sarah (primary group sarah) creates a file, it is owned by group sarah. But because she is also a member of sudo, developers, and docker, she can access files with group permissions set for any of those groups.

$ id sarah
uid=1000(sarah) gid=1000(sarah) groups=1000(sarah),27(sudo),1001(developers),998(docker)

Sarah can:

  • Run sudo commands (membership in sudo group)
  • Read/write files owned by the developers group with appropriate permissions
  • Manage Docker containers (membership in docker group)

All of these access rights come from supplementary group memberships.

Adding a user to a supplementary group:

$ sudo usermod -aG developers sarah

The -a (append) flag is essential — without it, the -G option replaces all current supplementary groups rather than adding to them.

Checking all group memberships:

$ groups sarah
sarah : sarah sudo developers docker audio video

$ id sarah
uid=1000(sarah) gid=1000(sarah) groups=1000(sarah),27(sudo),1001(developers),998(docker),29(audio),44(video)

The newgrp Command: Switching Active Groups

Your primary group affects which group owns files you create. If you need to create files for a specific group without changing your permanent primary group, newgrp creates a new shell with a different active group:

$ newgrp developers

Now you are in a subshell where your active group is developers. Files you create in this shell are owned by developers:

$ touch shared_script.sh
$ ls -l shared_script.sh
-rw-r--r-- 1 sarah developers 0 Feb 18 10:15 shared_script.sh

Exit the subshell with exit to return to your original session with your normal primary group.

When newgrp is useful: When working on a project directory where you want everything you create to automatically belong to the project group, without permanently changing your primary group.

How Group Permissions Work with Files

The Group Permission Bits

Recall from the file permissions article: every file has three sets of permission bits — owner, group, and others. The group bits (positions 5–7 in the permission string) determine what members of the file’s associated group can do:

$ ls -la /projects/team/
drwxrwxr-x 3 alice developers 4096 Feb 18 09:00 .
-rw-rw-r-- 1 alice developers 2048 Feb 18 10:15 design.txt
-rwxr-xr-x 1 bob   developers 1024 Feb 17 14:30 build.sh
-rw-r--r-- 1 carol developers  512 Feb 16 11:20 notes.txt

For design.txt with permissions -rw-rw-r--:

  • Owner (alice): rw- — can read and write
  • Group (developers): rw- — can read and write
  • Others: r-- — can only read

Any member of the developers group — sarah, alice, bob, carol, or anyone else in the group — can read and write design.txt. Users not in developers can only read it.

For build.sh with permissions -rwxr-xr-x:

  • Owner (bob): rwx — can read, write, and execute
  • Group (developers): r-x — can read and execute, but not modify
  • Others: r-x — can also read and execute

All developers can run build.sh, but only bob can modify it.

Setting Group Permissions

When creating files for group collaboration, set the group write bit:

$ touch shared_notes.txt
$ chmod g+w shared_notes.txt        # Add write permission for group
$ ls -la shared_notes.txt
-rw-rw-r-- 1 sarah developers 0 Feb 18 10:22 shared_notes.txt

Or set permissions numerically:

$ chmod 664 shared_notes.txt        # rw-rw-r--
$ chmod 775 shared_script.sh        # rwxrwxr-x

Changing a File’s Group

The chgrp command changes which group is associated with a file:

$ chgrp developers shared_notes.txt

Regular users can change a file’s group to any group they belong to. Changing to a group you are not a member of requires root.

Change group recursively for a directory:

$ sudo chgrp -R developers /projects/team/

The umask and Group Permissions

The umask determines default permissions for new files. The default umask of 022 produces:

  • Files: 644 (rw-r–r–) — group cannot write by default
  • Directories: 755 (rwxr-xr-x) — group cannot write by default

For collaborative group environments where you want group members to be able to edit each other’s files, change the umask to 002:

$ umask 002

With umask 002:

  • New files: 664 (rw-rw-r–) — group can read and write
  • New directories: 775 (rwxrwxr-x) — group can read, write, and traverse

Add umask 002 to ~/.bashrc to make this permanent for your sessions. Or set it system-wide in /etc/profile or /etc/bash.bashrc.

The SetGID Bit: Enforcing Group Inheritance

One of the most powerful group features is the SetGID (set group ID) bit on directories. When a directory has SetGID set, all files and subdirectories created within it automatically inherit the directory’s group — regardless of the creating user’s primary group.

Why SetGID on Directories Is Essential for Collaboration

Without SetGID, a collaborative directory has a problem: each user creates files owned by their own primary group, not the shared group. Alice creates files owned by alice:alice, Bob creates files owned by bob:bob, and other developers cannot write them without permission changes.

With SetGID on the directory, all files are automatically owned by developers regardless of who created them — immediately accessible to all group members.

Setting Up a Collaborative Directory with SetGID

# Create the shared directory
$ sudo mkdir -p /projects/team_alpha

# Set ownership to a developer and the shared group
$ sudo chown alice:developers /projects/team_alpha

# Set permissions: owner full, group full, others read+traverse
# The 2 prefix sets the SetGID bit
$ sudo chmod 2775 /projects/team_alpha

# Verify
$ ls -la /projects/
drwxrwsr-x 2 alice developers 4096 Feb 18 10:30 team_alpha

The s in the group execute position (rwsr-x) indicates SetGID is set.

Now when any developer creates a file:

$ sudo -u bob touch /projects/team_alpha/bob_notes.txt
$ ls -la /projects/team_alpha/
-rw-r--r-- 1 bob developers 0 Feb 18 10:35 bob_notes.txt

Bob’s file is owned by developers, not bob — immediately readable and (with group write permissions) writable by all developers. No manual chgrp or chmod needed.

The Complete SetGID Collaborative Directory Setup

For a directory where all developers can create, read, modify, and delete each other’s files:

$ sudo mkdir -p /shared/project
$ sudo chown root:developers /shared/project
$ sudo chmod 2775 /shared/project

Developers’ files:

  • Automatically owned by developers group (SetGID)
  • Group-readable and writable (umask 002 or explicit chmod g+w)

This pattern is the standard approach for shared development directories, collaborative work folders, and any resource meant for a specific team.

Creating and Managing Groups

Creating a New Group

$ sudo groupadd groupname

Create with a specific GID:

$ sudo groupadd -g 1500 projectteam

Create a system group (low GID, for services):

$ sudo groupadd --system webapps

Deleting a Group

$ sudo groupdel groupname

Note: You cannot delete a group that is the primary group of any user. Remove or reassign those users’ primary groups first.

Deleting a group does not delete files owned by that group — those files remain but their group field shows the now-orphaned GID number rather than a name. Find and reassign them:

$ sudo find / -gid 1500 -type f 2>/dev/null

Renaming a Group

$ sudo groupmod -n newname oldname

Modifying a Group’s GID

$ sudo groupmod -g 1600 groupname

Warning: Changing a GID means all files previously associated with that group by GID retain the old GID number — they become associated with whatever group (if any) has the new GID, or become orphaned. This is rarely done on production systems.

Managing Group Members with gpasswd

gpasswd manages group membership and can optionally set a group administrator:

$ sudo gpasswd -a username groupname    # Add user to group
$ sudo gpasswd -d username groupname    # Remove user from group
$ sudo gpasswd -M user1,user2,user3 groupname    # Set entire member list
$ sudo gpasswd -A admin_user groupname  # Set group administrator

Verifying Group Changes

$ getent group groupname
developers:x:1001:sarah,alice,bob,carol

$ cat /etc/group | grep developers
developers:x:1001:sarah,alice,bob,carol

Important: Group membership changes take effect at next login for the changed user. Existing sessions do not pick up new group memberships automatically. For immediate effect:

$ newgrp developers      # Starts a new shell with the new group active

Or have the user log out and back in.

System Groups and Their Purposes

Linux distributions include many system groups pre-configured for specific purposes. Understanding these groups explains how hardware access, system services, and administrative functions are controlled.

Common System Groups on Ubuntu

Group GID Purpose
root 0 The root/superuser group
sudo 27 Members can use sudo for full admin access
adm 4 Can read system log files in /var/log
cdrom 24 Can access CD/DVD drives
audio 29 Can access audio devices
video 44 Can access video devices and webcams
plugdev 46 Can access removable storage devices
lpadmin 120 Can manage printers
docker varies Can manage Docker containers
www-data 33 Web server process group
ssl-cert varies Can read SSL/TLS private keys
shadow 42 Can read /etc/shadow

Hardware Access Through Groups

Linux uses groups to control access to hardware devices. Instead of requiring root to use a USB drive or play audio, users in the appropriate group get access automatically:

  • Members of audio can use /dev/audio, /dev/snd/ (sound devices)
  • Members of video can use /dev/video0 (webcams), /dev/dri/ (GPU)
  • Members of plugdev can mount removable media

When you plug in a USB drive, udev creates the device file with the plugdev group and appropriate permissions. Members of plugdev can mount and access the drive; others cannot.

This is why adding a user to the correct groups matters on multi-user workstations: a new account that is not in audio cannot play sound. Not in video cannot use a webcam.

The docker Group: A Common Example

Adding a user to the docker group is a common task:

$ sudo usermod -aG docker sarah

After logging out and back in, Sarah can run Docker commands without sudo:

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Without group membership:

$ docker ps
permission denied while trying to connect to the Docker daemon socket

This pattern — a group that grants access to a specific service’s socket or resource — is used by Docker, libvirt (virtual machines), KVM, and many other services.

Practical Group Design Patterns

Pattern 1: Team-Based Collaboration

A software company has three teams: frontend, backend, and devops. Each needs their own shared space, with some cross-team sharing:

# Create team groups
$ sudo groupadd frontend
$ sudo groupadd backend
$ sudo groupadd devops
$ sudo groupadd engineering   # Umbrella group for all developers

# Assign users
$ sudo usermod -aG frontend,engineering alice
$ sudo usermod -aG frontend,engineering bob
$ sudo usermod -aG backend,engineering carol
$ sudo usermod -aG backend,engineering dave
$ sudo usermod -aG devops,engineering,sudo eve

# Create shared directories
$ sudo mkdir -p /projects/{frontend,backend,shared}

# Frontend directory: only frontend team
$ sudo chown root:frontend /projects/frontend
$ sudo chmod 2770 /projects/frontend    # No access for others

# Backend directory: only backend team
$ sudo chown root:backend /projects/backend
$ sudo chmod 2770 /projects/backend

# Shared directory: all engineering
$ sudo chown root:engineering /projects/shared
$ sudo chmod 2775 /projects/shared    # Others can read

Pattern 2: Read-Only Access for Auditors

An auditor needs to review files but not modify them:

$ sudo groupadd auditors
$ sudo usermod -aG auditors frank

# Files group: engineering, permissions: owner rw, group r, others none
$ sudo chmod 640 sensitive_report.txt
$ sudo chgrp engineering sensitive_report.txt

But this does not give Frank (auditors) access. The solution: use ACLs (Access Control Lists) for more granular access, or create a read-only copy owned by the auditors group, or restructure so auditors get read access through a different path.

For simple cases, a dedicated read-only directory:

$ sudo mkdir /audit_files
$ sudo chown root:auditors /audit_files
$ sudo chmod 750 /audit_files    # auditors can read and traverse

# Copy files for audit (or link them)
$ sudo cp -r /projects/shared /audit_files/
$ sudo chown -R root:auditors /audit_files/shared/
$ sudo chmod -R 640 /audit_files/shared/    # auditors can read, not write

Pattern 3: Service Account Isolation

A web application runs as webapp user. It needs to read configuration but should not write to it. The database credentials file should only be readable by the web application:

$ sudo groupadd webapp_secrets
$ sudo usermod -aG webapp_secrets webapp

# Only the service account and root can read this
$ sudo chown root:webapp_secrets /etc/myapp/database.conf
$ sudo chmod 640 /etc/myapp/database.conf
# Result: rw-r----- (root can rw, webapp_secrets group can read, others nothing)

Querying Group Information

Listing All Groups

$ cat /etc/group
$ getent group              # Includes groups from LDAP/NIS if configured

Finding Groups a User Belongs To

$ groups username
sarah : sarah sudo developers docker audio video

$ id username
uid=1000(sarah) gid=1000(sarah) groups=1000(sarah),27(sudo),1001(developers),998(docker),29(audio),44(video)

Finding Members of a Group

$ getent group developers
developers:x:1001:sarah,alice,bob,carol

$ grep "^developers:" /etc/group
developers:x:1001:sarah,alice,bob,carol

Finding Files Owned by a Group

$ find /projects -group developers -type f
$ find / -gid 1001 -type f 2>/dev/null    # Search by GID

Checking If a User Is in a Group

$ id sarah | grep -o "developers"
developers

$ groups sarah | grep -q "developers" && echo "In group" || echo "Not in group"
In group

Quick Reference: Group Management Commands

Task Command
Create a group sudo groupadd groupname
Delete a group sudo groupdel groupname
Rename a group sudo groupmod -n newname oldname
Add user to group sudo usermod -aG groupname username
Remove user from group sudo gpasswd -d username groupname
Set full member list sudo gpasswd -M user1,user2 groupname
View group members getent group groupname
View user’s groups groups username or id username
Change file’s group chgrp groupname filename
Change file’s group (recursive) sudo chgrp -R groupname directory/
Set SetGID on directory sudo chmod g+s directory/ or sudo chmod 2775 directory/
Find files by group find /path -group groupname
Switch active group newgrp groupname
Check group info getent group groupname

Conclusion: Groups as the Architecture of Sharing

Groups are the mechanism by which Linux transforms from a system where files are either private or universally accessible into one where precise, controlled sharing is possible. By thoughtfully creating groups, assigning users to appropriate groups, and configuring file and directory permissions around those groups, you create an access control architecture that reflects the actual structure of your organization or project — who needs access to what, and at what level.

The patterns are consistent across all Linux systems: teams get groups, shared resources get group ownership, SetGID directories enforce group inheritance, and the umask or explicit chmod controls whether group members can write to each other’s files. Master these patterns and you have mastered one of Linux’s most powerful collaboration mechanisms.

Whether you are setting up a small home server shared between family members, a development workstation shared by a team, or administering user access on a production Linux server, groups are the tool that makes sensible, secure sharing possible. They are simple enough to understand quickly, powerful enough to handle complex access control requirements, and universal enough that the same concepts apply across every Linux distribution you will ever encounter.

Hot this week

Understanding the Linux Man Pages: Your Built-in Documentation

Learn how to use Linux man pages to look up any command, understand its options, and navigate the built-in documentation system. Includes man, info, apropos, and whatis.

How to View Running Processes in Linux

Learn how to view and manage running processes in Linux using ps, top, htop, pgrep, and pstree. Understand process states, PIDs, CPU/memory usage, and how to find and kill processes.

What Is BASH? Understanding the Linux Shell

Learn what Bash is, how the Linux shell works, the difference between the terminal and the shell, Bash features every user should know, and how to customize your shell environment.

How to Check Your Linux System Information

Learn how to check Linux system information including OS version, kernel, CPU, RAM, disk space, network, and hardware details using essential terminal commands.

How to Add and Remove Users in Linux

Learn how to add, remove, and manage user accounts in Linux using useradd, adduser, userdel, and usermod. Covers passwords, home directories, groups, and best practices.

Topics

Understanding the Linux Man Pages: Your Built-in Documentation

Learn how to use Linux man pages to look up any command, understand its options, and navigate the built-in documentation system. Includes man, info, apropos, and whatis.

How to View Running Processes in Linux

Learn how to view and manage running processes in Linux using ps, top, htop, pgrep, and pstree. Understand process states, PIDs, CPU/memory usage, and how to find and kill processes.

What Is BASH? Understanding the Linux Shell

Learn what Bash is, how the Linux shell works, the difference between the terminal and the shell, Bash features every user should know, and how to customize your shell environment.

How to Check Your Linux System Information

Learn how to check Linux system information including OS version, kernel, CPU, RAM, disk space, network, and hardware details using essential terminal commands.

How to Add and Remove Users in Linux

Learn how to add, remove, and manage user accounts in Linux using useradd, adduser, userdel, and usermod. Covers passwords, home directories, groups, and best practices.

What Is a Linux Repository and How Does It Work?

Learn what a Linux software repository is, how package managers use repositories to install and update software, and how to add, remove, and manage repositories safely.

Understanding Linux Package Formats: .deb vs. .rpm

Linux software is distributed in two major package formats:...

How to Compress and Extract Files in Linux

Learn how to compress and extract files in Linux using tar, zip, gzip, bzip2, and xz. Complete guide with practical examples for every format you will encounter.

Related Articles

Popular Categories