Creating and Managing Accounts
Create, modify, disable, verify, and remove Linux user and group accounts through a controlled, auditable lifecycle.
Learning objectives
By the end of this lesson
- Plan an account lifecycle before creating a Linux user.
-
Use
useradd,usermod,gpasswd,passwd, anduserdelsafely. - Distinguish primary groups, supplementary groups, home directories, and login shells.
- Lock, expire, and remove accounts without confusing those operations.
- Verify every identity change through NSS and filesystem state.
1. Accounts have a lifecycle, not just a creation command
An account should be created from an explicit requirement, assigned
only the access it needs, reviewed while active, disabled promptly
when no longer required, and removed only after ownership and
retention questions are resolved. The difficult part is not typing
useradd; it is preserving traceability and avoiding
abandoned data, orphaned files, or excessive group membership.
Identify the owner, purpose, duration, authentication method, and whether the identity is human or non-human.
Choose the username, UID policy, primary group, home, shell, and supplementary groups deliberately.
Resolve the identity through NSS, inspect memberships, test the intended operation, and confirm ownership.
Remove unnecessary memberships, lock authentication or expire the account, and preserve evidence.
Decide what happens to home directories, scheduled work, files elsewhere, audit records, keys, and tokens.
flowchart TD R["Approved requirement"] --> C["Create account and home"] C --> G["Assign least-privilege groups"] G --> V["Verify identity and access"] V --> W["Periodic review"] W --> D["Disable or expire"] D --> O["Find owned resources"] O --> X["Remove, archive, or transfer"]
2. Account-management tools and distribution differences
useradd is a low-level, scriptable tool available
across major Linux families. Some Debian-derived systems also
provide adduser, a higher-level policy wrapper with
interactive defaults. Their behavior is not interchangeable in
automation. Read the local manual and inspect defaults before
assuming that a home directory, user-private group, or shell will be
created automatically.
# Inspect local defaults before creating anything
useradd -D
getent passwd "$USER"
getent group "$(id -gn)"
# Locate the relevant commands and manuals
command -v useradd usermod userdel passwd chage gpasswd
man useradd
man login.defs
For scripts, specify important properties explicitly rather than relying on site defaults. Idempotent configuration-management tools are preferable when many hosts must converge on the same account state.
3. Understand the properties you are changing
useradd -u
useradd -g
usermod -aG
useradd -m -d
usermod -s
passwd -l/-u/-S
chage -E
The primary group field is stored in the user's account record.
Supplementary memberships may be stored in group records or supplied
remotely. When adding a supplementary group with
usermod, omitting -a while using
-G can replace the entire existing supplementary group
list.
usermod -G newgroup user sets the supplementary list.
usermod -aG newgroup user appends. Always capture
id user before and after a membership change.
4. Create, modify, and verify
The following pattern uses an isolated lab account. Run it only in a disposable VM or lab host where you have authorization. It deliberately leaves password assignment interactive and avoids embedding credentials in shell history.
# Lab-only names
lab_user=da_account_lab
lab_group=da_platform_lab
# Refuse to overwrite an existing identity
if getent passwd "$lab_user" >/dev/null; then
printf 'Account already exists: %s\n' "$lab_user" >&2
exit 1
fi
# Create a supplementary group and a user-private primary group/home
sudo groupadd "$lab_group"
sudo useradd --create-home --shell /bin/bash "$lab_user"
sudo usermod --append --groups "$lab_group" "$lab_user"
# Set a password interactively only if password login is required
sudo passwd "$lab_user"
# Verify records and filesystem ownership
getent passwd "$lab_user"
getent group "$lab_group"
id "$lab_user"
sudo stat -c 'path=%n owner=%U(%u) group=%G(%g) mode=%A' "/home/$lab_user"
A created account is not automatically entitled to use SSH, sudo, a desktop, or a particular application. Those are separate policies. Conversely, a locked password does not necessarily prevent SSH keys, existing sessions, scheduled jobs, or service tokens from working.
5. Disable and remove without losing control
Choose the mechanism that matches the intended state. Password locking changes the password verifier; account expiration is broader; changing the shell can block conventional interactive login; removing SSH keys or directory access revokes other authentication paths. Offboarding must address all of them.
lab_user=da_account_lab
lab_group=da_platform_lab
# Capture evidence before disabling
id "$lab_user"
sudo passwd --status "$lab_user"
sudo chage --list "$lab_user"
# Lock the password and expire the account immediately
sudo passwd --lock "$lab_user"
sudo chage --expiredate 1 "$lab_user"
# Verify the disabled state
sudo passwd --status "$lab_user"
sudo chage --list "$lab_user"
# Before deletion, locate files owned outside the home directory.
# Keep the search on one filesystem and review results manually.
sudo find / -xdev -uid "$(id -u "$lab_user")" -print 2>/dev/null
# Lab cleanup: remove the account and its home, then the lab group
sudo userdel --remove "$lab_user"
sudo groupdel "$lab_group"
Review running processes, cron jobs, systemd units, SSH keys, API credentials, files on other filesystems, mail spools, shared directories, and external identity systems before deleting an account.
6. Hands-on lab: execute a documented account change
Repeat the lifecycle with a second temporary account, but create an evidence file before and after each change. This trains the verification habit used in change management.
lab="$HOME/devops-academy/linux/chapter07/lesson02"
mkdir -p "$lab"
log="$lab/account-change.log"
lab_user=da_change_lab
lab_group=da_release_lab
{
printf '=== change started %s ===\n' "$(date -Is)"
printf 'operator=%s host=%s\n' "$(id -un)" "$(hostname)"
} > "$log"
sudo groupadd "$lab_group"
sudo useradd --create-home --shell /bin/bash "$lab_user"
sudo usermod --append --groups "$lab_group" "$lab_user"
{
printf '\n=== created ===\n'
getent passwd "$lab_user"
getent group "$lab_group"
id "$lab_user"
sudo stat -c 'home=%n owner=%U(%u) group=%G(%g) mode=%A' "/home/$lab_user"
} >> "$log"
sudo passwd --lock "$lab_user"
sudo chage --expiredate 1 "$lab_user"
{
printf '\n=== disabled ===\n'
sudo passwd --status "$lab_user"
sudo chage --list "$lab_user"
} >> "$log"
sudo userdel --remove "$lab_user"
sudo groupdel "$lab_group"
printf '\n=== cleaned up %s ===\n' "$(date -Is)" >> "$log"
chmod 600 "$log"
less "$log"
Verification checklist
7. Common mistakes
Relying on implicit defaults
Home creation, group policy, shell, and UID ranges vary. Specify critical properties and verify the result.
Using -G without -a
This can remove every supplementary membership not listed in the command.
Deleting before inventory
Files elsewhere may become numerically orphaned, while jobs, tokens, or keys continue to exist.
Embedding passwords in commands
Command history, process listings, logs, and CI output can expose credentials. Use approved interactive or secret-management channels.
8. Knowledge check
Question 1. What is the difference between locking a password and expiring an account?
Question 2. Why is usermod -aG safer than
usermod -G for adding one group?
-a option appends to the current supplementary
group list. Without it, -G replaces the list with
only the groups named in the command.
Question 3. What should be checked before
userdel -r?
9. Summary
Account management is a controlled lifecycle. Create identities with explicit properties, assign the minimum groups required, verify the resolved records and filesystem state, disable every relevant authentication path during offboarding, inventory owned resources, and remove only after retention decisions are complete.
10. Further reading
-
Linux man-pages:
useradd(8),usermod(8), anduserdel(8). -
Linux man-pages:
groupadd(8),gpasswd(1),passwd(1), andchage(1). -
Your distribution's
login.defs(5)and account-management policy. - Organizational joiner, mover, and leaver procedures.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.