SGID Explained

SGID Explained

SGID is a special permission bit whose behavior actually splits into two genuinely different effects depending on whether you apply it to a file or a directory. The directory behavior is by far the more commonly used of the two on modern Linux systems.

SGID on files: group privilege inheritance

ls -l some_program
# -rwxr-sr-x 1 root developers 45000 Jul 9 program
#          └── an 's' here in the group execute position

On an executable file, SGID causes the program to run with the privileges of the file’s owning group, rather than the group of whoever actually launched it. This mirrors what SUID does for the owning user, but for the group instead. This specific use case, SGID on files, is considerably rarer in modern practice than its counterpart on directories, though it still exists in a handful of legacy system utilities.

SGID on directories: the far more common use case

mkdir team_project
sudo chown colton:developers team_project
sudo chmod 2775 team_project
ls -ld team_project
# drwxrwsr-x 2 colton developers 4096 Jul 9 team_project
#         └── the 's' confirms SGID is active

On a directory, SGID means every new file or subdirectory created inside it automatically inherits the directory’s own group, rather than defaulting to whichever primary group the creating user happens to have.

# Without SGID: alice's own primary group is used
touch team_project/notes.txt
ls -l team_project/notes.txt
# -rw-r--r-- 1 alice alice ... notes.txt
#                     └┬──┘
#              alice's OWN primary group, not "developers"

# With SGID set on the directory: the directory's group is inherited instead
touch team_project/notes.txt
ls -l team_project/notes.txt
# -rw-r--r-- 1 alice developers ... notes.txt
#                     └───┬───┘
#              inherited from the DIRECTORY, regardless of
#              alice's own primary group

Why this solves a real, recurring problem

Without SGID, every file a team member creates inside a shared directory defaults to their own individual primary group, which very often does not match whatever group is supposed to collectively own the team’s shared files. This means someone has to manually run chgrp on every new file, a step that is easy to forget, especially across a team of several people all contributing files over time.

# The manual alternative, without SGID, that everyone has to remember every time:
touch newfile.txt
chgrp developers newfile.txt
chmod g+w newfile.txt

Setting SGID on the shared directory once, up front, eliminates this entirely: every file created inside it from that point forward automatically belongs to the correct shared group, with zero ongoing manual effort required from anyone on the team.

SGID propagates to nested subdirectories automatically

mkdir team_project/subfolder
ls -ld team_project/subfolder
# drwxrwsr-x ... subfolder
#          └── SGID was inherited automatically, not just the group

This is one of SGID’s most useful properties on directories: a new subdirectory created inside an SGID directory does not just inherit the correct group, it also inherits the SGID bit itself. This means the entire behavior propagates automatically through however many levels of nested subdirectories get created underneath the original SGID directory, without anyone needing to manually reapply chmod g+s at every level of a growing project structure.

Setting and checking SGID

chmod g+s directoryname
chmod g-s directoryname

# numeric mode: leading digit 2 represents SGID
chmod 2775 directoryname

As with the sticky bit and SUID, numeric mode uses a leading fourth digit for SGID specifically, 2, which can be combined with SUID (4) and the sticky bit (1) in the same leading digit if more than one special permission is needed at once, for example 6 (4+2) for both SUID and SGID together, though combining special bits this way is unusual outside of specific, deliberate configurations.

Reading s vs S for SGID

ls -ld dir_with_group_execute
# drwxrwsr-x ... (lowercase s: SGID set, group execute also present)

ls -ld dir_without_group_execute
# drwxrw-r-x ... wait, this would actually show as:
# drwxrwSr-x ... (uppercase S: SGID set, but group execute is missing)

The same case convention applies here as with the sticky bit and SUID: lowercase s means the special bit is set alongside the normal execute permission it depends on to be meaningful; uppercase S flags an unusual combination where the special bit is set but the corresponding execute permission is absent, generally worth double-checking as a possible misconfiguration.

Frequently Asked Questions

What does the SGID bit do?

SGID (Set Group ID) has two different effects depending on whether it is applied to a file or a directory. On an executable file, it makes the program run with the privileges of the file’s owning group rather than the group of the user who launched it. On a directory, it causes every new file and subdirectory created inside it to automatically inherit the parent directory’s group, instead of defaulting to the creating user’s own primary group.

Why is SGID on directories so commonly used for shared team folders?

Without SGID, every new file created inside a shared directory defaults to the creating user’s own primary group, which often does not match the group that should actually own shared team files. This means team members frequently end up needing to manually chgrp every new file to the correct shared group. Setting SGID on the directory once means every file and subdirectory created inside it from then on automatically gets the directory’s own group, keeping shared team storage consistent with no manual intervention.

How do I set SGID on a directory and verify it worked?

Run chmod g+s directoryname, or in numeric mode, chmod 2775 directoryname, where the leading 2 represents SGID. Verify it with ls -ld directoryname, looking for an s in the group execute position instead of the usual x.

Does SGID on a directory apply to subdirectories created inside it automatically?

Yes, and this is one of its most useful properties: when a new subdirectory is created inside an SGID directory, that new subdirectory also inherits the SGID bit itself, not just the group ownership. This means the inheritance behavior propagates automatically through an entire nested directory tree created under the original SGID directory, without needing to manually reapply chmod g+s at every level.

What is a real-world example of SGID on an executable file, rather than a directory?

The classic historical example is the wall command on some Unix systems, which needed group privileges to write messages to other users’ terminal devices. On modern Linux, SGID on executable files is considerably less common in practice than SGID on directories, since the directory-inheritance use case for shared team storage covers the vast majority of real-world SGID usage today.

How can I tell if a directory has SGID set just from ls -l output?

Look at the group execute position in the permission string. A lowercase s there means SGID is set and group execute permission is also present. An uppercase S means SGID is set but group execute permission is missing, an unusual combination since it would prevent group members from entering the directory at all, making the inheritance behavior somewhat moot for them specifically.