The reference page taught you the commands. The lab will make you run them. But there's a third thing worth knowing before you sit down to do the lab: most cyber-forward companies don't actually administer Linux this way anymore. They administer the concepts — users, groups, access, storage — but the tooling is two abstraction levels above useradd.
This page is a warm-up: a quick tour of how a senior engineer at a modern cloud-native company would solve each of the eight problems from the reference. You'll see what tools you're likely to meet in your first job, and — more importantly — why the underlying Linux primitives still matter even when you never type useradd directly.
Identity moved off the machine.
The single change underneath almost everything here: accounts no longer live on individual servers. They live in an Identity Provider — Okta, Microsoft Entra ID (formerly Azure AD), Google Workspace, JumpCloud, AWS IAM Identity Center — and they get pushed to every system the user needs access to.
When a new hire's record appears in the HR system (Workday, BambooHR, Rippling), a webhook fires. The IdP creates the user. SCIM 2.0 (the standard protocol for cross-system identity sync) pushes that user into every connected SaaS app, every Linux fleet via the IdP's agent, every cloud provider's IAM, every VPN. One create operation; hundreds of downstream accounts.
When the same person leaves, the reverse happens. HR flips the bit, SCIM revokes everywhere, and within seconds they can't log into anything. The off-boarding step you'll do by hand in the lab — the careful, multi-step disable — is what an automated pipeline does in milliseconds, on every system, every time.
Creating users
Local accounts, one machine at a time
useradd on every server. Twenty servers, twenty useradd commands. Twenty places to remember when someone leaves.
Works fine for a homelab or one server. Stops working as soon as the fleet gets to three machines.
Identity provider + SCIM
User created once in the IdP. SCIM 2.0 (or the IdP's native agent) pushes the account to every Linux server, every SaaS, every cloud account.
The Linux server doesn't have a row in /etc/passwd for the user. Instead, SSSD (or the IdP's agent) makes the IdP look like a local user database to PAM and NSS.
Okta, Microsoft Entra ID, Google Workspace, JumpCloud, AWS IAM Identity Center. Plus the Linux side: SSSD for AD/LDAP joins, realmd for the join command itself, or vendor agents like the JumpCloud Linux agent. Provisioning is driven by SCIM from the IdP and triggered by an HRIS (Workday, BambooHR, Rippling) integration.
Why the underlying Linux still matters: SSSD ultimately exposes the IdP user as a regular Unix UID/GID. Permissions, file ownership, sudo — all still flow through the kernel's POSIX model. When you debug "why can alice read this file but not bob," you're reading id alice output, not the Okta dashboard.
Passwords & aging
Local password policy with chage
Set a temporary password with passwd, force a change with chage -d 0, enforce a 90-day rotation with PASS_MAX_DAYS.
Each server gets its own copy of the policy. Each user has a different password on each system unless something synchronizes them.
Passwordless — or central + WebAuthn
Most modern auth flows skip passwords entirely. Users sign into the IdP with a passkey (FIDO2 / WebAuthn) and get into everything via SSO. Where passwords still exist, they live in the IdP, not on the machine.
The 90-day rotation policy is mostly gone, replaced by NIST 800-63B guidance: rotate only on evidence of compromise. Forced rotation correlates with weaker passwords, not stronger ones.
Authentication via passkeys (FIDO2 / WebAuthn) backed by hardware (YubiKey, Touch ID, Windows Hello). Where passwords remain, they sit behind an IdP with conditional access rules — "Alice can sign in only from a managed device, only from these regions, only with MFA." Detection-side: impossible-travel alerts in the SIEM, automatic credential revocation when a leak is detected.
Why the lab still matters: Many production Linux fleets still have a local root password as a break-glass account. The same fleets have service accounts whose passwords live in a secret manager (Vault, AWS Secrets Manager). The mechanics of passwd, chage, and /etc/login.defs still describe what's happening on the kernel side; the IdP and secret manager just sit on top.
Disabling accounts
Manual, multi-step, per-machine
Lock the password, expire the account, change the shell, kill sessions, wipe authorized_keys, remove crontabs. Repeat on every machine they had access to.
If you miss a server, the off-boarded employee can still log in there.
One flip in the IdP, fan-out everywhere
HR marks the employee as terminated. HRIS webhook fires. IdP deprovisions. SCIM revokes from every connected system — SaaS apps, cloud IAM, Linux fleet via SSSD — in seconds.
Short-lived SSH certificates (next topic) mean their existing access tokens can't outlive the next refresh. Within minutes, the off-boarded employee has nothing.
Lifecycle automation via Okta Workflows, Entra ID Lifecycle Workflows, or JumpCloud Directory Insights. SIEM-driven revocation: a Splunk SOAR or Tines playbook can pull credentials globally the instant a compromise indicator fires. The off-boarding runbook becomes a YAML file in version control.
Why the lab still matters: the checklist you'll work through by hand is identical to what the automation does — lock auth, end sessions, kill scheduled tasks, revoke keys, audit before delete. The automation is just running the checklist faster than you can. Knowing the checklist by hand is what lets you debug what the automation missed.
Groups & RBAC
/etc/group on each machine
groupadd, usermod -aG. Membership is local to the server. Add a new engineer → touch every server they need access to.
sudo rights are in /etc/sudoers on each machine, often as ad-hoc edits.
Groups in the IdP, RBAC everywhere
Groups live in the IdP. Add alice to the engineering group in Okta; SCIM pushes the membership to every Linux server, every SaaS app, every AWS account.
Sudo rules ship via centrally-managed sudoers — Vault, JumpCloud, or Ansible — not by editing a file on each box. RBAC at the cloud layer (AWS IAM, GCP IAM, Azure RBAC) is keyed off the same group.
SSSD with AD/LDAP for traditional joins, vendor agents for modern IdPs. Sudo management via HashiCorp Vault, JumpCloud, or Ansible. Higher up the stack, AWS IAM Identity Center maps IdP groups to AWS permission sets across multiple accounts — the cloud equivalent of "the engineering group has read access to the prod S3 bucket."
The pattern is identical: grant permissions to groups, put users in groups, never grant a permission to a named individual. The lab teaches you this discipline using chmod 2770 on a shared directory. At a modern company, you'll do the same thing in an IAM policy or a Kubernetes RoleBinding — the syntax changes; the principle doesn't.
Directories & shared storage
mkdir, chmod, chgrp on a host
Run commands on a server, set permissions manually, hope no one drifts the configuration later.
If you rebuild the server, you re-do all of it. The state lives only in the running filesystem.
Infrastructure as Code, or no host at all
Directory layout, ownership, and permissions are declared in Ansible, Terraform, Pulumi, or a Kubernetes manifest. The state lives in Git; the server is reproducible.
Increasingly, the "directory" isn't a directory at all — it's an S3 bucket, a Cloud Storage object, a Persistent Volume Claim in Kubernetes, or a managed network file system (EFS, Filestore, Azure Files).
Ansible roles for filesystem layout. Terraform for cloud storage (S3, EFS, GCS). Kubernetes PersistentVolume + PersistentVolumeClaim for container workloads, backed by a CSI driver. For object storage: S3 bucket policies, IAM bucket conditions, server-side encryption with KMS keys. Permissions on objects are an IAM policy, not a chmod.
Why the lab still matters: when a Kubernetes pod mounts a PVC, the kernel inside the pod is still using POSIX permissions. When an S3 bucket policy gets misconfigured, the failure shows up as "the read returned 403." Understanding what permission bits and group ownership mean at the kernel level is what lets you debug across the abstractions.
SSH — what replaced it
Long-lived keys, edit sshd_config
Generate an SSH key once, copy it to every server. The same key works for years. If the laptop gets stolen, you rotate keys on every server.
Disable root login by editing sshd_config. Test with sshd -t. Restart.
Ephemeral certificates & session brokers
SSH keys, when used, are certificates that expire in minutes. Authenticate to a broker (Teleport, Vault SSH-CA, Smallstep CA) with your IdP. Broker mints a cert valid for 5 minutes. SSH the box with that cert. The cert expires before the meeting ends.
Or skip SSH entirely: session brokers like AWS SSM Session Manager, GCP IAP, and Azure Bastion start a shell on the target via API. No port 22 open to the internet. No keys at all.
Teleport — the most common modern SSH/identity broker. HashiCorp Vault SSH secrets engine — mints short-lived certificates signed by a CA the servers trust. Smallstep step-ca for the open-source path. Session brokers: AWS SSM Session Manager (no SSH ports open), GCP IAP TCP forwarding, Azure Bastion. Zero-trust overlays: Tailscale SSH, Cloudflare Access, BeyondCorp.
What is identical: the server still runs sshd, still reads sshd_config, still uses the same authorized-keys mechanism — the difference is that the keys it accepts are signed certificates rather than static public keys. Disabling root SSH (PermitRootLogin no) is still best practice; it just happens to be enforced by the IaC pipeline now instead of a human editing a file. The lab's sshd_config edits are the contract that the modern automation implements.
Containers & workload isolation
chroot, jails, single-purpose VMs
Run a daemon in a chroot. Spin up a whole VM for one workload. Heavy, slow, and chroot leaks under adversarial pressure.
Containers, orchestrated by Kubernetes
Every workload runs in a container. Containers use Linux namespaces + cgroups — the proper kernel features chroot was reaching for.
Kubernetes schedules them across a fleet. Security-sensitive workloads run under gVisor, Kata Containers, or AWS Nitro Enclaves for harder isolation. Observability via eBPF and tools like Falco for runtime detection.
Docker and Podman for local development. Kubernetes (EKS / GKE / AKS) for production orchestration. containerd and CRI-O as the actual runtimes. Image registries: ECR, Artifact Registry, Docker Hub, Harbor. Hardened runtimes: gVisor, Kata Containers. Runtime security: Falco, Tetragon, CrowdStrike Cloud Workload Protection.
Why the lab still matters: a Kubernetes pod is, at the kernel level, a process inside a set of namespaces with cgroup limits applied. When you debug "why can the container reach this host file?" you're debugging mount namespaces. When you debug "why is the container OOM-killed?" you're debugging cgroups. The lab's chroot section teaches the ancestor of the abstraction you'll use every day.
Storage — cloud-native
Mount a disk at a directory
Add a disk, partition it, format it, edit /etc/fstab, mount it. State lives on the host.
Networked storage via NFS or SMB, with their own mount syntax.
Mostly objects, sometimes volumes
Default storage is object storage: S3, Cloud Storage, Azure Blob. There is no mount — the application talks HTTPS to the bucket.
Where filesystems still exist, they're EFS / Filestore / Azure Files for shared access, or EBS / Persistent Disk for block. In Kubernetes, the application asks for a PersistentVolumeClaim; a CSI driver provisions the volume and the kernel mounts it inside the pod.
Object: Amazon S3, Google Cloud Storage, Azure Blob Storage. Block: EBS, Persistent Disk, Azure Managed Disks. Shared filesystems: EFS, Filestore, Azure Files, FSx. Kubernetes: CSI (Container Storage Interface) drivers for each. Encryption: server-side with KMS keys, client-side for the paranoid.
The "mount vs. map" question gets a third answer in 2026: neither, for most modern apps. You don't mount, you don't map — you make an API call. GET s3://bucket/object retrieves the bytes; there's no path in the OS that holds them. The lab teaches the model that still applies inside containers and on VMs; the cloud-native model adds "or just talk to a URL" as a fourth pattern alongside local, NFS, and SMB.
Every modern abstraction on this page compiles down to the same kernel primitives you'll exercise in the lab. SSSD looks up users in Okta and exposes them as Unix UIDs. Kubernetes pods are namespaced processes. S3 access denials are POSIX permission errors at a higher abstraction level. The mechanics didn't get easier; they just got hidden behind better tools.
When something breaks — and at every cyber-forward company, something breaks every day — the engineer who can pop open a shell, run id, read /etc/shadow, check journalctl -u sshd, and trace the request down to the actual kernel call is the one who fixes it. The IdP didn't go down; SSSD failed to refresh because the LDAP TLS cert rotated. Until you can debug at the Linux layer, you don't get to operate the modern abstractions on top of it.
That is what the lab is for. Go do the lab.
A quick map
If you encounter one of these in the wild, here's the traditional command it maps to:
| You'll see in a modern shop | It's doing the equivalent of |
|---|---|
| Okta → SCIM → SSSD | useradd on every server in the fleet, all at once |
| Lifecycle Workflow runs on termination | The full usermod -L -e 1 -s nologin disable recipe, plus session kill, plus key wipe — on every system at once |
| Okta group "engineering" → SSSD | groupadd engineering + usermod -aG engineering <user>, fleet-wide |
| Vault SSH-CA + ssh -i <short-lived cert> | ssh-copy-id, except the "copy" only lasts five minutes |
| AWS SSM Session Manager | SSH into the box, except sshd isn't listening on port 22 at all |
| Ansible role for /etc/fstab + mounts | mount /dev/sdb1 /srv/data, but reproducibly, in Git |
| S3 bucket with IAM policy | NFS export with mount options, except the "filesystem" is HTTP |
| Kubernetes pod with PSP/PSA | chroot, except with namespaces, cgroups, and seccomp filters — the actual hard isolation |
| HashiCorp Vault PAM module | /etc/sudoers editing, but the rules live in Vault and rotate |
References
Formatted in APA 7 — the citation style your coursework will use. Notice the structure: Author(s). (Year). Title of work (Report/Identifier number). Publisher. URL. Reading citations carefully is the first step toward writing them yourself.
- Amazon Web Services. (n.d.). AWS Systems Manager Session Manager. https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html
- Grassi, P. A., Fenton, J. L., Newton, E. M., Perlner, R. A., Regenscheid, A. R., Burr, W. E., Richer, J. P., Lefkovitz, N. B., Danker, J. M., Choong, Y.-Y., Greene, K. K., & Theofanos, M. F. (2017). Digital identity guidelines: Authentication and lifecycle management (NIST Special Publication No. 800-63B, Rev. 3). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-63b
- HashiCorp. (n.d.). SSH secrets engine. Vault documentation. https://developer.hashicorp.com/vault/docs/secrets/ssh
- Hunt, P., Grizzle, K., Ansari, M., Wahlstroem, E., & Mortimore, C. (2015). System for cross-domain identity management: Protocol (Request for Comments No. 7644). Internet Engineering Task Force. https://datatracker.ietf.org/doc/html/rfc7644
- Kubernetes CSI Special Interest Group. (n.d.). Kubernetes container storage interface (CSI) documentation. https://kubernetes-csi.github.io/docs/
- Rose, S., Borchert, O., Mitchell, S., & Connelly, S. (2020). Zero trust architecture (NIST Special Publication No. 800-207). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-207
- SSSD Project. (n.d.). SSSD: System security services daemon. https://sssd.io/
- Teleport. (n.d.). Teleport architecture overview. https://goteleport.com/docs/architecture/overview/
- Ward, R., & Beyer, B. (2014). BeyondCorp: A new approach to enterprise security. ;login:, 39(6), 6–11. https://research.google/pubs/pub43231/