Software · General — accounts & permissions

User Accounts & Permissions: Local Accounts, Admin Rights, and Least Privilege

30-tutorial collection6 categories × 5 tutorialsWindows & Linux

A local account is the identity a machine answers for on its own: its name, credentials, groups and permissions live on that one computer, and nothing outside it can grant or revoke them. That makes local accounts both simpler than directory identities and more exposed — there is no central policy to catch a stray administrator membership, so the discipline has to live on the machine.

This collection teaches that world in order. Six categories cover what local identities are and how they differ from online accounts, how to create and manage them on Windows and Linux, what administrative rights actually allows, how least privilege turns those rights into a controllable system, and how to audit, harden and verify the result — 30 tutorials, each one a distinct procedure or decision. Use the table of contents to jump straight to a topic, or search it by command, concept or platform.

A local identity and the resources it can reach A circuit diagram. A central node labelled with a person symbol represents the local account on one computer. Dashed circuit traces connect it to six resource chips: files, applications, network, services, system settings, and other users. Small pulses travel along three of the traces to show access checks. A dashed rectangle around the whole diagram marks the trust boundary of this single machine. trust boundary — this machine only SYSTEM FILES APPS NETWORK SERVICES OTHER USERS
Every access decision on a local machine starts here: an identity, checked against the resource it wants to reach. Least privilege is about keeping that set of reachable chips as small as the task allows — and making sure you know exactly which chips they are.

Category 1 · How local identities work

Local Account Fundamentals

Before you can create, secure or audit an account, you need a working model of what the operating system actually stores and checks. These five tutorials build that model from the bottom up: where an identity lives, how proving who differs from deciding what you may do, why numeric identifiers beat names, and which built-in identities are part of the machine rather than people.

Everything here is scoped to the local machine. Domain and cloud identities get a fair comparison in tutorial 04, but the point of this category is that on a standalone computer the account store is the authority — there is no central server to call when you sign in.

Understanding Local User Accounts and How They Work

In this tutorial: Explain what a local account is, where its identity and configuration are stored on a single machine, and how authentication (proving who you are) differs from authorization (what you may do).

A local user account is an identity that exists only on one machine. Its name, password material and configuration are stored in the operating system's own account database — on Windows in the protected SAM store (a secured system file you cannot open like a document), on Unix-like systems in /etc/passwd for account records and /etc/shadow for password hashes. Because the store lives on the device, a local account can authenticate even when the machine has no network at all, and its authority stops exactly at that machine's boundary.

Two distinct questions are often blended into one. Authentication answers "are you really who you claim to be": the system compares what you supply (password, PIN) against the stored hash and either accepts or rejects the sign-in. Authorization then answers "what may this identity do": group membership, file permissions and security policies decide which files, settings and operations are reachable. A local account's authentication data and its authorization data sit next to each other in the same machine — there is no directory server consulted along the way.

On a personal computer or standalone workstation, signing in with a local account creates and loads a per-user environment: Windows builds a profile under C:\Users\<name> holding settings, documents and application data; Linux sets up a home directory plus shell and configuration files. Each user's session state is isolated from the others', which is why two people can use one machine without seeing each other's windows, bookmarks or credentials. The account is the handle the OS uses to find that environment.

It helps to keep local identities separate from online and directory identities rather than treating them as versions of the same thing. A Microsoft sign-in on Windows or a domain account both ultimately produce a local identity on that device, but their source of truth differs: a local account's identity is authoritative only here, while an online or directory identity is managed elsewhere and may carry policies from that other system. Confusing the two leads to mistakes like assuming that resetting a cloud password also resets what a machine allows — it does not.

Verify your understanding: on Windows run net user in a terminal to list the local identities and their account type; on Linux run getent passwd to see the account records with their numeric IDs. Both commands read the local store directly, which is exactly what "local" means. Tutorial 03 goes deeper into those identifiers.

Standard Users, Administrators, and System Accounts

In this tutorial: Distinguish standard users, administrators, built-in identities, and service accounts - their intended purposes, security boundaries, and which activities actually require elevation.

A standard user is the intended default for daily work. On Windows this means a member of the local Users group; on Linux, an ordinary account with no privileged group membership. A standard identity can run applications, change its own settings and files, and print — but it cannot install most software system-wide, modify other users' files, change security policies or manage devices. That boundary is deliberate: it limits what a compromised application or a mistaken click can reach.

An administrator on Windows holds full control over the local machine: installing software, managing every user and file, changing system settings. The subtlety many users miss is that an administrator's everyday session is not automatically fully privileged — User Account Control splits the session into a filtered token for normal work and a full token that must be explicitly requested (tutorial 12 covers the mechanics). On Linux there is no such split: root is the ceiling, and ordinary users reach it temporarily through sudo rather than logging in as root itself.

Built-in and service accounts are identities that belong to the system rather than to a person. Windows ships with several — the built-in Administrator, Guest, DefaultAccount, WDAG Utility Account, and web/IIS identities such as IUSR — each wired into specific components. Linux keeps a similar population: system and service accounts (typically UID below 1000) that own processes, daemons and jobs, usually without an interactive login shell. These accounts exist so that parts of the OS can run under identities with only the permissions those parts need.

Comparison of standard users, administrators, root and service accounts: purpose and which activities require elevated privileges
Identity typeIntended purposeInstall software system-wideChange other users' filesAlter security settings
Standard user (Windows)Daily work for a personNo (per-user installs only)NoNo
Administrator (Windows)Maintenance and configuration, by design elevated per actionYesYesYes
root (Linux)Full system control; reached via sudo, not used for daily loginYesYesYes
Service / built-in accountRun OS components and daemons with minimal reachRarely intendedOnly where the component needs itNo (scoped to its role)

Three misconceptions are worth naming. First, "administrator" does not mean "the machine is mine to break" — ownership rules, policies and, on Windows, UAC still constrain even a full admin token in ways that matter during troubleshooting (tutorials 15 and 27). Second, one shared administrator account per computer is a common but costly habit: when two people act under the same identity, no log entry can say which of them did what. Third, service accounts are not invisible — they hold real permissions, which is exactly why auditing them (tutorial 05) matters.

Check your setup: on Windows open Settings → Accounts → Other users (or lusrmgr.msc where available) and note each account's type; on Linux run id <username> for each human user and check whether the output lists any privileged group. A healthy personal machine shows exactly one or two human accounts, with at most one of them in a privileged group.

User IDs, Security Identifiers, Groups, and Account Ownership

In this tutorial: Explain how operating systems identify users and groups numerically (SIDs on Windows, UIDs/GIDs on Unix), why names alone are not identity, and how ownership relates to permissions.

Operating systems do not decide access by name — names are display labels. Windows identifies every identity with a Security Identifier (SID), a long string such as S-1-5-21-<machine-number>-<account-number>. The machine portion is generated when the OS is installed, so two users created with the same name on two different PCs have completely different SIDs. Unix-like systems use smaller integers: a UID for users and a GID for groups, mapped to names in /etc/passwd and /etc/group. In both worlds the number is what permissions actually reference.

This is why name-based reasoning fails in specific, predictable ways. Rename a Windows user and its SID does not change, so access-control entries that referenced it keep matching the same identity — the Security tab of a file may show a raw SID instead of a friendly name precisely because the account was renamed or removed. On Linux, if an entry disappears from /etc/passwd but files remain, those files are now owned by a bare number with no name to resolve. In neither case does "the name is gone" mean "the permissions are gone".

Group membership is the multiplier that makes permission management tractable. Instead of granting each person access individually, you grant the group and manage membership. Your effective access on a resource is the combination of everything your user entry and all of your groups carry — on Windows, explicit deny entries override every allow; on POSIX systems there is no deny at all, only the presence or absence of permission bits for owner, group and others. Inspect your own position in this structure with net user <name> (Windows) or id <name> (Linux): both print the groups that actually count.

Ownership is a relationship distinct from permission. The owner of a resource has a special standing: on NTFS an owner can typically change the access-control list even when the owner lacks Full Control, and taking ownership is its own operation (takeown) separate from granting access. On POSIX the "user" column of ls -l names the owner, and the first triplet of permission bits applies to that owner alone. Ownership changes hands through explicit transfer (takeown / icacls on Windows, chown on Linux), never by accident — which is why it comes up again in the access-denied diagnostics of tutorials 26 and 27.

Windows security identifiers compared with Unix user and group IDs: storage, format, groups, denial and ownership
ConceptWindows (NTFS/SAM)Unix-like (POSIX)
Identity recordSAM store, keyed by SID/etc/passwd, keyed by UID
Identifier formatSID string (machine-unique at install)Integer UID / GID
Group modelLocal groups; membership shown in Security tab and net userPrimary group + supplementary groups (id)
Deny mechanismExplicit deny ACEs override allowsNo deny — absence of a bit is the only "no"
Ownership effectOwner can often edit the ACL; transfer via takeownFirst permission triplet applies to owner; transfer via chown (root)

Keep one rule of thumb: when something about access "looks wrong", check the identifier and the group list before touching permissions. Most confusing permission problems are really stale SIDs, missing group membership or an ownership mismatch wearing a familiar name.

Local Accounts Versus Microsoft Accounts and Domain Accounts

In this tutorial: Compare local accounts, Microsoft accounts, and domain identities across authentication dependency, device scope, recovery, and policy - keeping the sign-in identity separate from the permissions it carries.

A standalone local account keeps its identity, password and recovery options on the device. It signs in offline without hesitation, and if you forget the password the recovery path is local — a security question or reset flow that runs on the machine itself. The trade-off is scope: nothing follows you to another computer, and no central system can enforce policy on this one.

A Microsoft account used to sign in to Windows changes where identity is managed, not what the machine permits. Authentication goes through Microsoft's online service (with an optional offline fallback PIN so the PC stays usable without internet), settings and some credentials can sync across your devices, and password recovery happens through Microsoft's infrastructure rather than on the box. The critical distinction: a Microsoft-account sign-in still lands as either a standard or an administrator identity on this device. "Signed in with a Microsoft account" says nothing about local privileges — that is set separately, and it is the part this whole collection is about.

A domain account (Active Directory) moves identity to a central directory. The machine joins the domain; sign-in is typically verified against a domain controller using Kerberos, with cached credentials allowing limited offline sign-in when controllers are unreachable. Group Policy objects can then push configuration and security settings to every joined machine from one place, and an account's access spans many devices rather than one. If your work computer behaves this way, the local tutorials still apply to what happens on the device — but the identity itself is administered by your organization (see the site's Active Directory and Group Policy guides for the enterprise side).

Local, Microsoft and domain accounts compared across storage, authentication, offline behavior, recovery and policy management
DimensionLocal accountMicrosoft account (on Windows)Domain account (AD)
Where identity is storedOn the device (SAM)Online service; local profile on deviceCentral directory (domain controllers)
Authentication pathLocal hash checkOnline verification, offline fallback PINKerberos vs domain controller; cached credentials offline
Device scopeOne machine onlyMany of your devices via syncAny joined machine the account is granted on
Password recoveryLocal reset flow / security questionsMicrosoft account recovery processHelp desk / directory administrator
Policy managementNone central — per-machine settingsService-level (Microsoft 365 etc.), not local OS policyGroup Policy from the domain
Typical fitPersonal PC, privacy-focused setupsPersonal ecosystem across devicesWorkplace / school-managed machines

The practical takeaway is a two-question habit. First: which system authenticates me? — the device, an online service, or a directory. Second: what does this device authorize that identity to do? — standard or admin, which groups, which files. Answering both keeps you from the two most common confusions: assuming cloud recovery fixes local lockouts (it usually does not), and assuming an "administrator" sign-in is automatically elevated in everyday use (on Windows it is not, until a prompt is approved).

Built-in Accounts, Guest Access, and Service Identities

In this tutorial: Identify built-in accounts, guest access, and service identities, learn their legitimate uses and risks, and see why disabling one without checking dependencies can break things.

Every Windows installation carries identities that no human created. The built-in Administrator account is the most powerful local identity and is often renamed or left password-protected in consumer setups; Guest is disabled by default on modern Windows 10/11, and enabling it means anyone at the machine can sign in without a password — an immediate exposure of everything Guest can read. Hidden accounts such as DefaultAccount and WDAG Utility Account serve specific internal features (data protection and system maintenance paths); they look odd in a user list, but that is their job.

Service identities are the accounts processes run under. In Windows Services each entry has a "Log On As" property — many run as Local Service, Network Service or a named account chosen for the permissions its component genuinely needs. Linux expresses the same idea in unit files (User=, Group= for systemd units) and in the accounts that own daemons and cron jobs. The security logic is identical on both platforms: if a service is compromised, the attacker inherits exactly that account's reach — so a web server running under a minimal dedicated account limits the blast radius far more than one running as an administrator.

Which accounts deserve a look? A short review checklist works well: every identity you cannot name a purpose for; any account with no password or a password that never changes; any non-human account sitting in an administrative group; and Guest, if it is enabled at all. On Windows, Get-LocalUser (or lusrmgr.msc) lists local accounts with their enabled state; on Linux, scan /etc/passwd for entries with a real login shell — those are the ones a person could actually use. Tutorial 21 turns this checklist into a repeatable audit.

The caution that keeps this section honest: disabling or modifying built-in identities without knowing their dependencies breaks things, and the failure often appears later, not at the moment of the change. A service account referenced by a systemd unit or a Windows service will cause that component to fail on next start; a web identity removed from its pool stops anonymous access. The safe sequence is: identify the account's purpose, find what depends on it (services, scheduled tasks, unit files), disable rather than delete when in doubt, and watch for failures before deciding the account can go permanently.

Bottom line: built-in and service accounts are part of the machine's plumbing. Treat them like electrical wiring — you do not need to rebuild it, but you should know what each line feeds before you switch anything off.

Category 2 · Creating, managing and retiring accounts

Account Creation and Lifecycle Management

Accounts are living things: they get created, change roles, and eventually need to be retired. This category covers the full lifecycle on both major platforms — graphical tools and command lines on Windows, useradd/usermod/userdel on Linux, PowerShell as the scriptable middle path, and group administration where most real access decisions live.

Every procedure here states its privilege requirement up front, shows how to verify the result, and names what breaks if you skip a step. The lifecycle tutorial (10) ties creation and removal into one documented process, because unmanaged offboarding is where most permission problems start.

Creating and Managing Local Accounts in Windows

In this tutorial: Create, inspect, disable, and remove local Windows accounts using Settings, lusrmgr.msc, and net user - with the implications of each operation and how to verify the result.

Windows offers two working interfaces for local account management. The first is Settings → Accounts → Other users: choose "Add account", then the path "I don't have this person's sign-in info" → "Add a user without a Microsoft account" creates a genuine local account with a name and password. The second is the command line from an elevated prompt — net user for single-account operations and, on Pro/Enterprise/Education editions, lusrmgr.msc (Local Users and Groups) for a full graphical view of users and groups together. Both manipulate the same local store; pick whichever you can verify most easily.

Command prompt (elevated) — create, inspect, disable
net user alice "P@ssw0rd-123" /fullname:"Alice Example"
net user alice                :: inspect the account, its type and status
net user alice /active:no     :: disable (reversible; profile is preserved)
net user alice /delete        :: remove the account (see warning below)

Creating an account is allowed for administrators only. The password must satisfy the machine's password policy, or the command fails with a policy error.

After creating an account, verify three things before calling it done. First, that the identity exists with the intended type: net user alice should report "Local Group Membership : *Users" for a standard account — anything else (especially Administrators) means someone elevated it. Second, that the profile materializes on first sign-in: switch to the new account at the lock screen and confirm C:\Users\alice appears with Documents and Settings populated. Third, that sign-out and re-sign-in both work cleanly, since profile problems usually surface on the second login.

Disabling versus deleting is the decision this tutorial keeps coming back to. A disabled account (/active:no) cannot sign in but retains its SID, its files, its profile and any group membership — re-enabling restores everything. Deletion removes the sign-in identity permanently; the files under C:\Users\alice remain until explicitly removed, becoming an orphaned profile that other administrators can still browse. Before deleting, work through tutorial 10's offboarding checklist: who owns which files, which scheduled tasks or services reference the account, and whether any shared folders depend on it.

!

Deleting an account is irreversible for its sign-in capability. If the account appears in any service's "Log On As" property, any scheduled task, or any file permission you do not understand, disable it first and revisit after a week of normal operation.

Windows Settings app on the Accounts, Other users page showing a list of local accounts with an Add account button
Settings → Accounts → Other users — where local accounts are added and their type changed — images/uap-06-settings-other-users.png

Change the account type deliberately. Making someone an administrator is net localgroup Administrators alice /add (elevated prompt); removing them is /delete. Treat group membership as a permission, not a formality — it is the single largest access change available on a local machine, and tutorial 21 shows how to audit who holds it.

Creating and Managing Local Users in Linux

In this tutorial: Manage local Linux users with useradd, adduser, usermod, passwd, and userdel - including home-directory handling, shells, distribution differences, and verification steps.

Linux account management lives in a small set of utilities from the shadow-utils package, present on virtually every distribution. The core four are useradd (create), usermod (modify), passwd (passwords) and userdel (remove). On Debian and Ubuntu you will often see adduser instead — a friendlier interactive wrapper around the same machinery; on RHEL, Fedora and openSUSE the bare useradd is the norm. All of them require root or sudo, because they write to /etc/passwd, /etc/shadow and /etc/group.

Bash — create and inspect (run with sudo)
sudo useradd -m -s /bin/bash alice      # -m creates /home/alice from the skeleton tree
sudo passwd alice                       # set the password; account is locked until this runs
id alice                                # uid, gid and groups — verify before anything else
ls -ld /home/alice                      # home exists, owned by alice:alice

A freshly created account has no usable password: interactive login will be refused until passwd has set one. That locked state is a feature, not an error.

Modifications go through usermod, and one flag deserves special care: adding to a supplementary group is sudo usermod -aG docker alice. The -a (append) is what makes it safe — without it, -G replaces the entire supplementary group list, silently dropping memberships the user relied on. Other common operations: changing the shell (-s /bin/sh), setting an expiration date (-e YYYYMMDD) and renaming (-l). Inspect the result with id alice and getent passwd alice, which print exactly what the system will use at login.

Removal is where care matters most. sudo userdel alice deletes the account records but leaves the home directory, mail spool and — critically — any files alice owned elsewhere on the disk. Add -r to remove the home and mail spool as well, but even then files outside those locations survive, now owned by a bare UID with no name. Before removing anyone, list what they own (sudo find / -user alice 2>/dev/null on a scoped set of paths), check for cron jobs and services running as that user, and decide explicitly where ownership should transfer. A deleted account with orphaned files is the Linux equivalent of the orphaned Windows profile from tutorial 06.

!

Distribution differences are real: UID ranges for regular users (commonly 1000 and up), default group behavior (Debian creates a same-named primary group; RHEL-style systems may share users), and which shells exist in /etc/shells all vary. When in doubt, read the man page for your distribution's useradd rather than trusting a generic example.

Verify the full loop: create with useradd, set the password, confirm with id and ls -ld, then test an actual login from another session (or a TTY) — login is the only check that exercises PAM, the shell and the home directory together. If login fails after all records look correct, the usual suspects are a missing password, a non-login shell such as /usr/sbin/nologin, or a home directory with wrong ownership.

Managing Local Users and Groups with PowerShell

In this tutorial: Inspect and change local users and groups with PowerShell's LocalUsers module, knowing which operations need elevation, how to handle errors, and where the module does not exist.

PowerShell's LocalUsers module (shipped with Windows 10 version 1709 and later, and Windows Server 2016 onward) gives you typed, scriptable account management without dropping to net strings. The read side needs no elevation: Get-LocalUser, Get-LocalGroup and Get-LocalGroupMember let any user inventory the machine. The write side — New-LocalUser, Set-LocalUser, Enable-LocalUser/Disable-LocalUser, Remove-LocalUser, and Add-LocalGroupMember/Remove-LocalGroupMember — requires an elevated session, and the commands fail with access-denied errors rather than silently doing nothing.

PowerShell — read-only inventory (no elevation needed)
# List every local account with its state and last sign-in
Get-LocalUser | Format-Table Name, Enabled, PasswordRequired, LastLogon -AutoSize

# Who is in an administrative group? (read-only)
Get-LocalGroupMember -Identity "Administrators" |
  Select-Object Name, PrincipalSource

# Inspect one account in detail
Get-LocalUser -Name "alice" | Format-List *

This snippet is safe to run anywhere: it only reads. Keep auditing scripts read-only — mutation belongs in a separate, reviewed script.

When you do write, structure the script so failures are visible instead of swallowed. Check that the target account exists before acting on it, stop the pipeline on first error, and print what changed.

PowerShell — guarded change (elevated)
$ErrorActionPreference = "Stop"
try {
    $acct = Get-LocalUser -Name "alice" -ErrorAction Stop
    if (-not $acct.Enabled) {
        Enable-LocalUser -Name "alice" | Out-Null
        Write-Output "Re-enabled: alice"
    }
} catch [Microsoft.PowerShell.Commands.RuntimeCmdletException] {
    Write-Warning ("Account operation failed: " + $_.Exception.Message)
}

Run from an elevated prompt. The try/catch turns "Access is denied" (not elevated) and unknown-account errors into readable messages instead of a raw stack trace.

Know the compatibility edges before relying on this in scripts. The LocalUsers module is absent from older Windows 10 builds and from some minimal server configurations — a quick Get-Module -ListAvailable LocalUsers tells you whether it exists on the target. On systems without it, net user/net localgroup remain the portable fallback (tutorial 06). And note what PowerShell does not do: Remove-LocalUser, like net user /delete, removes the identity but leaves the profile under C:\Users — orphaned-profile cleanup is a separate, deliberate step on every interface.

Failure cases worth recognizing: "Access is denied" means the session is not elevated; an account that is currently signed in cannot be deleted or renamed; and group operations against protected built-in groups (like the local Administrators group's trusted entries) can fail even for administrators — read the error text, it names the exact entry that was rejected.

Managing Users and Groups with Linux Command-Line Tools

In this tutorial: Administer Linux groups and membership with id, groups, getent, groupadd, and gpasswd - primary versus supplementary groups, safe membership changes, and verification of effective access.

Group administration is where most real access decisions happen on Linux, because permissions are usually granted to groups rather than individuals. The inspection trio is id <user> (prints the UID, primary GID and every supplementary group), groups <user> (names only) and getent group <name> (the raw /etc/group record: name, password field, GID and member list). Together they answer the question "what will this user actually match at access check time?" — which is a different question from what any single configuration file says in isolation.

The distinction between primary and supplementary groups drives most confusion. Every user has exactly one primary group, set at creation (-g) or defaulted by the distribution (Debian-style systems create a same-named group; others may assign users). New files the user creates take the primary group's GID automatically. Supplementary groups are additional memberships granted with -G at creation or later via usermod -aG; they extend access without changing default ownership. A file owned by alice:projects is readable by the group projects only if its group permission bits allow it — membership and bits are two separate facts that must both be true.

Bash — create a group and manage membership (sudo)
sudo groupadd projects                 # create the group; GID assigned automatically
sudo gpasswd -a alice projects         # add member (gpasswd is the membership tool)
sudo gpasswd -d bob projects           # remove member
getent group projects                  # verify: name:x:<gid>:alice,bob?
id bob                                 # verify bob's effective groups after a NEW login

usermod -aG does the same membership change as gpasswd -a; pick one convention per system and stick to it.

The classic operational trap: group changes do not apply to already-running sessions. Group memberships are read when a session starts, so adding alice to projects changes nothing for her currently open terminal. Verify with a fresh login (new TTY, re-login, or sg projects -c 'ls /shared' which runs one command under the group). When a "membership I just added" apparently does not work, this stale-session effect is the first thing to rule out before suspecting the permission bits themselves.

Distribution notes: groupadd/gpasswd come from shadow-utils and exist on all major distributions, but GID allocation ranges and whether a same-named primary group gets created differ. More importantly for security work, the "which group means administrator" question is distribution-specific — wheel on RHEL-family systems, sudo on Debian/Ubuntu by default — and tutorial 22 shows how to audit privileged membership without assuming one answer fits everywhere.

Account Onboarding, Offboarding, and Recovery Procedures

In this tutorial: Run a structured account lifecycle - onboarding, authorization changes, offboarding, and recovery - and understand why disabling an account differs from deleting it.

A managed account lifecycle has four phases with explicit gates: create, authorize, verify and retire. Onboarding starts with two decisions made before any command runs: what type of identity this is (a person's daily account, a service identity, or an administrative one) and what privilege level it needs on day one. The default answer to the second question should be standard — privilege gets added later, per need, not pre-emptively. Then create with the platform's normal tools (tutorials 06–09), set a compliant password, grant only the groups the role requires, and verify with an actual sign-in plus a check of id/net user output that matches the plan.

Authorization is ongoing, not one-time. Roles change: a teammate joins a project group, a contractor's access expires, someone who was an admin leaves maintenance work. Each change should be small, named (which group, which direction), and recorded — date, account, change, who made it, why. That record is what makes the later audits in tutorials 21–25 interpretable instead of archaeological digs, and it is the difference between "we can explain this membership" and "nobody remembers".

Offboarding is where disabling beats deleting in almost every case. A disabled account (Windows /active:no; on Linux, locking with passwd -l or expiring the account) preserves the identity, its files, its ownership relationships and every permission entry that references it — and it is reversible in one command. Deletion removes the sign-in capability permanently and orphans everything that pointed at the identity: files now owned by a bare SID or UID, scheduled tasks and cron jobs that fail on their next run, services whose "Log On As" no longer resolves. Before removing anyone, assess: which files and folders do they own, which jobs and services run under them, and which shared resources depend on their membership — then transfer ownership deliberately rather than discovering the gap later.

Recovery closes the loop for the locked-out case. On Windows a local account resets through its own recovery flow (security questions or a reset password set by another administrator); on Linux an administrator with root access can reset any local password, and root itself is reachable through the distribution's recovery mechanism. The deeper treatment — online identities, two-factor lockouts and the order to try recovery options in — lives in the site's passwords & accounts recovery guide; this tutorial's point is that a written lifecycle makes recovery a procedure instead of a panic.

Record template — one line per account event
# date | account | action | detail | by | verified?
2026-10-21 | alice | created   | standard user, groups: -        | dana | yes (id + login)
2026-11-02 | alice | authorized| added to group 'projects'       | dana | yes (new session)
2027-01-15 | bob   | disabled  | contract ended; files kept      | dana | yes (sign-in refused)

Six columns, one line. This is the minimum that keeps a later audit readable.

Category 3 · Admin rights, UAC and sudo

Administrative Rights and Privilege Elevation

Elevation is the mechanism that turns a normal session into a capable one — and it is the mechanism attackers want most. This category explains what administrator and root privileges actually allow, how Windows User Account Control and Linux sudo gate those powers, and how to elevate only the task that needs it instead of the whole session.

The troubleshooting tutorial (15) finishes the category with a diagnostic workflow for permission and elevation errors: identify which layer is actually failing before granting anything at all.

What Administrator and Root Privileges Actually Allow

In this tutorial: See concretely what Windows administrator and Unix root privileges allow - system configuration, protected files, services, software installation - and why excess privilege multiplies the cost of mistakes.

On Windows, being an administrator means membership of the local Administrators group — but that is only half the story. Because of User Account Control, an elevated session still starts with a filtered token: everyday operations run at medium integrity, and privileged operations must be explicitly elevated. What elevation unlocks is broad but not magical: installing software system-wide (writing to C:\Program Files and the HKLM registry), managing every local user and group, changing security policies, reading other users' files, and controlling services. Even so, Windows deliberately withholds some corners from ordinary administrators — files in protected system directories (the VBS-trusted paths under System32) are guarded by mandatory integrity levels, so "admin" cannot simply overwrite them without extra steps. That design exists precisely because administrator has historically been too easy to abuse.

On Unix-like systems the ceiling is different and flatter: root (UID 0) bypasses discretionary permission checks entirely. Root can read or write any file, signal any process, load kernel modules, reconfigure the network stack and change every account on the machine. Modern kernels split some of that power into capabilities (fine-grained fragments like CAP_NET_ADMIN), but a plain root shell holds all of them. sudo is the normal gate: it lets an authorized user run one command as root — or as another specific user — under policy and logging, instead of living in a root shell.

The cost of holding excess privilege is proportional to everything else running in your session. An application inherits the identity of whoever launched it: a browser opened from an elevated shell runs its extensions at that level, and a compromised application suddenly has your full administrative reach. The same logic applies to human error — a mistyped path in a root shell is a system-wide event, while the same mistake in a standard session usually fails harmlessly against a permission check. Privilege is not just a capability; it is a blast radius.

Capabilities compared across standard user, Windows administrator (elevated) and Linux root
CapabilityStandard userWindows admin (elevated)Linux root
Install software system-wideNo (per-user installs only)YesYes
Read other users' filesNoYes (most paths)Yes (all)
Manage local users and groupsNoYesYes
Change security policies / sudoersNoLocal policies yesYes
Control services / daemonsOwn user services onlyAll local servicesAll units
Modify protected system filesNoRestricted (integrity levels)Yes

Two misconceptions to retire: first, that an administrator "owns" the machine in an absolute sense — both platforms keep protected layers above ordinary admin rights; second, that administrative power is a single switch. It is a bundle of capabilities (group membership, token elevation, per-resource permissions) that can be granted and checked separately, which is exactly what the auditing tutorials in category 5 exploit.

Using Windows User Account Control Safely

In this tutorial: Understand UAC prompts, token filtering, and elevation requests; inspect and troubleshoot elevation behavior without disabling any security control.

UAC's job is to make elevation a visible, deliberate event. Under the default setting (level 2, "Always notify"), every process starts with a filtered medium-integrity token; when an operation needs more, Windows shows the consent prompt and — for members of Administrators — offers to activate that user's full token. A standard user sees a different prompt asking for administrator credentials, because their session contains no full token to activate at all. The prompt itself carries information: which application is requesting elevation, which user context it will run in, and (when available) the publisher. Reading those lines is most of the security value; clicking through them is how UAC stops protecting anything.

The practical rule for prompts you did not expect: cancel, then investigate before retrying. Where did the application come from — a folder you recognize, an installer you just ran, or somewhere else entirely? Check its location and digital signature (right-click → Properties → Digital Signatures), and if it is something you cannot place, treat it as suspicious input to the security guide in the site's troubleshooting section rather than approving it "to see what happens." An unexpected elevation request is one of the few signals that appears before damage, which makes it worth the extra minute.

Troubleshooting elevation behavior should never mean lowering the control. If a legitimate operation keeps prompting or failing, inspect rather than disable: confirm you are actually in the Administrators group (net localgroup Administrators), check whether the application requests elevation through its manifest (some apps always elevate; others only for specific features), and read the UAC policy values read-only:

PowerShell — read UAC policy state (read-only)
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" |
  Select-Object EnableLUA, ConsentPromptBehaviorAdmin, PromptOnSecureDesktop

EnableLUA=0 means UAC is off — on a healthy machine it should be 1. Do not set it to 0 to make prompts stop; fix the underlying application or workflow instead.

Windows User Account Control consent prompt on the secure desktop asking whether to allow a named application to make changes, with Yes and No buttons
A UAC consent prompt: note the application name, the user context line and the publisher — read all three before answering — images/uap-12-uac-prompt.png

Two edge cases deserve naming. First, the "Run as administrator" shortcut on an executable you do not recognize is a red flag in itself — legitimate software rarely needs you to manually elevate it from the file system. Second, UAC has a stricter mode (Admin Approval Mode) where even administrators must consent to their own elevation; it exists mainly for specialized environments and is not something to enable or disable casually on a personal computer. The consistent posture: prompts are information, the secure desktop is a feature, and "make the prompt go away" is never the fix.

Using sudo and Root Access Responsibly on Linux

In this tutorial: Use sudo and root access on Linux deliberately: command-scoped elevation, sudoers policy basics, sudoedit, and why running daily work as root is risky.

sudo authorizes a specific command, run as another identity (root by default), under the rules in /etc/sudoers. Your user remains the actor: the invocation is attributed to you, can be logged per policy, and a timestamp cache (~15 minutes by default) means you are prompted once and then trusted for that window. That is fundamentally different from su -, which hands you an unattributed root shell with no per-command policy and no natural end point. The design intent is visible in the difference: sudo is a key for individual doors, su is the master key to the whole building.

The safe patterns are about narrowing both identity and scope. To work with a database, run as the service's own account rather than root: sudo -u postgres psql — the command gets only what the postgres role can do. To edit a privileged configuration file, use sudoedit /etc/nginx/nginx.conf: you edit a temporary copy in your own editor and sudo writes it back as root, so you never open an editor inside a root shell (a classic way to drift into running arbitrary commands as root). Reserve plain sudo for commands that genuinely need full authority, and avoid sudo bash or sudo su - as a daily habit.

Bash — inspect your own sudo authorization (read-only)
# What am I allowed to run, and as whom?
sudo -l

# Narrow elevation: one command, specific target user
sudo -u postgres psql -c 'SELECT current_user;'

# Edit a privileged file without opening a root shell
sudoedit /etc/hostname

sudo -l is the first command to run on any new machine: it turns "what can I do here?" from guesswork into a list.

Sudoers policy is where authority is actually defined. A typical line — %admin ALL=(ALL:ALL) ALL — says members of the admin group may run anything as any user, on any host. Two modifiers deserve explicit respect: NOPASSWD removes the password gate that forces a beat of deliberation (if a workflow truly needs it, scope it to one command, e.g. Cmnd_Alias BACKUP = /usr/bin/rsync, %ops ALL=(root) NOPASSWD: BACKUP), and secure_path, which pins the PATH sudo uses so a trojaned /usr/local/bin cannot hijack elevated commands. A user who can edit their own sudoers entry to add NOPASSWD: ALL has, for practical purposes, root — which is why protecting that file (root-owned, mode 440) matters as much as the accounts it names.

The reason not to live in a root shell is simple arithmetic of mistakes. As root, rm -rf $DIR/ with an empty variable is not a failed command — it is a system event; a browser run as root puts every extension and web page at the top of the privilege ladder; and with no per-command boundary, there is no point where "I only meant to check one log" ends. Routine operation should be your own account plus deliberate, visible elevation — which is exactly the least-privilege posture Tutorial 16 formalizes.

Running Individual Administrative Tasks Without Elevating Everything

In this tutorial: Separate ordinary activity from privileged operations and elevate only the specific task - with worked Windows and Linux examples and a check that least privilege still holds afterwards.

The working habit is: the session stays standard; the task gets elevated. On Windows, that means right-clicking an application and choosing "Run as administrator" for a one-off elevated instance, or opening a dedicated elevated console that you close when the job is done:

PowerShell — open an elevated console for one task
# From your normal (non-elevated) PowerShell:
Start-Process powershell -Verb RunAs

# In the elevated window that opens, do exactly one job, e.g.:
Add-WindowsCapability -Online -Name "Net.Fax~0.0.1.0"

# Verify, then close the elevated window and return to normal.

The elevated window is a tool you pick up and put down — not a new home base. If you find yourself "just leaving it open," that is the habit to break.

On Linux the equivalent is scoping elevation to the command itself: sudo journalctl -u myservice reads one service's log with exactly the privilege that read needs, while sudo su - replaces your whole session with root. The sudo timestamp cache works in your favor here — you will be prompted once, then the next few sudo calls within ~15 minutes run without re-prompting — but treat that window as "a few related commands," not permission to drift into an all-day root session. When a task really needs several privileged steps, do them in one deliberate burst and return to your normal shell.

A worked Windows example makes the loop concrete. Task: install a driver package. (1) Open elevated PowerShell via Start-Process -Verb RunAs. (2) Run pnputil /add-driver C:\drivers\pkg.inf /install. (3) Read the result line — it names the installed driver package. (4) Close the elevated window. The change is now system-wide and verifiable from anywhere, including your standard session: Device Manager shows the new driver, and no elevated context is needed to confirm it.

The verification habit is what makes this safe rather than merely tidy. After an elevated task, confirm the outcome from a normal context — if a system-wide change is real, a standard user should be able to see its effects. Then run the inverse check occasionally: attempt something privileged from your normal session (for instance, creating a file in C:\Program Files, or on Linux running sudo -l to confirm your authorization list is still narrow). Being denied where you expect denial is proof that least privilege is actually in force — the denial is the feature working.

Troubleshooting Administrator Permission and Elevation Errors

In this tutorial: Diagnose access-denied and elevation errors at the layer that is actually failing - identity, token state, application requirements, policy, or resource permissions - instead of granting administrator rights by reflex.

The first move is to read the exact error, because each variant points at a different layer. "Access is denied" on a file is an authorization failure (your identity lacks that resource's permission). A UAC prompt asking for administrator credentials means you are a standard user — which is working as designed, not a fault. "The requested operation requires elevation" names the missing token. On Linux, Permission denied is a permission-bit or ownership failure, while sudo: username is not allowed to execute... means the sudoers policy deliberately scopes you out. Diagnosis starts by naming which of these layers actually failed.

The repair strategy that follows from this is to change exactly one variable at a time and retest. Elevation errors are compounding problems: a wrong group membership, a filtered token, an application manifest, and a restrictive policy can all be true on the same machine, and fixing them in a jumble makes it impossible to tell which fix actually worked — or whether a later change silently undid an earlier one. Each step below therefore produces evidence you can keep: the identity that ran, the state before the change, the single thing changed, and the result of the retest. When a step changes nothing, you have ruled out an entire layer; when it fixes the problem, you know the cause was in that layer, and you can choose the narrowest correction instead of the widest one.

  1. Confirm identity and groups. Windows: whoami and net localgroup Administrators. Linux: id.
  2. Confirm the session's privilege state. Windows: whoami /groups | findstr /i "High Mandatory" — a standard or filtered token shows Medium. Linux: your shell is either yours or root; there is no hidden middle tier.
  3. Check what the application itself requires. Does it request elevation in its manifest? Is a policy (AppLocker, parent controls, a locked-down kiosk) blocking it regardless of your groups?
  4. Inspect the target resource. For file failures, look at ownership and permissions directly — Windows: Security tab → Advanced → Effective Access; Linux: ls -l and the directory chain (Tutorials 26–27 cover both in depth).
  5. Only then change authorization — one membership or one ACE at a time, retest after each change, so you know which change fixed it.
Common elevation and permission symptoms with their likely causes and correct fixes
SymptomLikely causeCorrect fix (not "make them admin")
App install fails with access errorStandard user running a per-machine installerPer-user installer if offered, or elevate just that one install (Tutorial 14)
UAC asks for admin credentialsUser is in Users, not Administrators — by designEnter the admin credentials, or deliberately change account type with full understanding (Tutorial 02)
"Access denied" on a file you createdOwnership/ACL issue, not missing admin rightsEffective Access check + targeted ACE fix (Tutorial 27)
sudo: not allowed to executeSudoers policy scopes the command outRead sudo -l; ask for the specific command added, not blanket ALL (Tutorial 13)
Elevated app still cannot write a system pathProtected directory / integrity levelUse the supported mechanism (installer, service) rather than fighting VBS paths (Tutorial 11)

The anti-patterns are the ones that "work" and make things worse. Adding the user to Administrators as a first resort masks ACL problems, widens every future blast radius, and often does not even fix the original file-level denial. Disabling UAC or chmod 777-ing a directory removes the symptom by removing the check. The consistent principle: privilege errors are usually resource problems wearing identity costumes — find the layer that is actually failing before you grant anything at all.

Category 4 · Least privilege in practice

Least Privilege and Access Control

Least privilege is the design principle that turns everything earlier in this collection from information into structure: which identity gets which permission, over which resources, for how long. Tutorial 16 states the principle fully — once — and the rest of the category applies it to a personal computer, a shared workstation, individual files and folders, and time-limited access.

The running theme is trade-off management: restriction that breaks daily work gets worked around in unsafe ways, so every boundary here is paired with the workflow that keeps it usable.

Understanding the Principle of Least Privilege

In this tutorial: Understand least privilege as an engineering principle across scope, operations, duration, and identity - and how it caps the damage from both human error and compromise.

Least privilege, as an engineering practice rather than a slogan, means: every identity holds only the permissions its current task requires, and nothing more. That single sentence expands into four independent dimensions. Identity: the right account performs the action — one person per account, service work on service accounts. Scope: permissions attach to specific resources (a folder, a registry hive, a daemon) rather than to "the machine." Operation: read where read suffices, write where write is needed, execute only for code that should run. Duration: power granted for a task expires when the task ends. A system can violate any one dimension while satisfying the others — which is why "we use standard accounts" is not the same as practicing least privilege.

The principle earns its keep by capping two distinct failure classes, and it is worth being precise about what it does not do. It does not prevent human error — you can still type the wrong path — but a mistake made with standard privileges usually dies against a permission check, while the same mistake in an elevated session propagates system-wide. It does not prevent compromise — malware still runs as whoever executed it — but a compromised browser tab in a standard session cannot write to system directories, read other users' documents, or install persistence; the identical compromise under an always-elevated token can do all three. Least privilege converts "what went wrong" into "how far can it go," and the second question is the one that determines real-world damage.

The four dimensions of least privilege, with a typical violation and the control that addresses each
DimensionQuestion it answersTypical violationControl
IdentityWho is acting?Shared "admin" logins; apps running as the userOne person per account; service accounts for daemons (Tutorial 05)
ScopeWhich resources?Full Control on C:\ instead of the one project folderTargeted ACEs / group bits on named resources (Tutorial 19)
OperationWhat may be done to them?Write access where read is enoughRead-only grants; scoped commands like sudo -u (Tutorial 13)
DurationFor how long?"Temporary" admin membership that never endsTime-boxed grants with a scheduled revocation step (Tutorial 20)

The boundary between least privilege and "just use a standard account" matters. A standard account is one point on the spectrum — the right default for daily work, but it says nothing about what your admin account may do, what service identities hold, or how file permissions are drawn. Least privilege governs all of those: scoped elevation instead of permanent membership, dedicated low-privilege service accounts, and ACLs that grant read where read suffices. It also sets a floor on usability, because over-restriction has its own failure mode: when the safe path is harder than the unsafe one, people share passwords, copy files into writable locations, or chmod 777 their way out. The design question is never "minimum possible access" in the abstract — it is "the access these actual tasks need," observed from how the work really gets done.

With that framing, the rest of this category becomes application: a concrete account arrangement for one person (17), boundaries on a machine several people share (18), permission evaluation at the file level (19), and making administrative power temporary by construction (20). Later categories then audit whether the structure held (21–25) and repair it where it has drifted (26–30).

Designing a Least-Privilege Account Model for a Personal Computer

In this tutorial: Design a practical account arrangement for a personal computer that separates routine work from administrative maintenance without making normal tasks unusable.

A workable single-person model has two identities with strictly different jobs. The daily account — standard privileges, whether backed by a local account or a Microsoft account — signs in for everything routine: browsing, documents, media, most applications. The maintenance identity holds the administrative rights and is used only when a task genuinely needs them: installing system-wide software, managing drivers, adjusting security settings. On Windows you can run this as two accounts (sign in with the admin one only for maintenance windows) or as one admin account plus deliberate per-task elevation (Tutorial 14); on Linux, one standard account plus scoped sudo usually covers it, since elevation is per-command rather than per-session. The invariant in every variant: the identity you live in is not the identity that can install software.

Deciding what belongs where takes an honest inventory of your actual workflow. Most consumer software installs fine per-user without any elevation — check for a "just for me" option before assuming an admin password is needed. The apps that genuinely require system-level access (driver packages, some virtualization tooling, certain anti-cheat or DRM components) form a short list you can name and defend; each one gets its elevation at install time, not standing permission. If your list grows past a handful of entries, that is signal to investigate why — a long "must be admin" list on a personal machine usually means something is configured wrong rather than many apps being special.

The shared-household variation keeps the same invariant per person: each family member gets their own standard account (never a shared login), one adult holds the maintenance identity, and children's accounts use the platform's built-in family controls instead of elevated access. This is also where "I'll just use Mom's account to install it" habits get broken — the maintenance account exists precisely so that installing software is a deliberate, attributable event rather than an everyday by-product.

Before committing to the model, run the usability test: live in the standard configuration for a week and let the friction surface. A game launcher that cannot create its files, a printer driver that demands admin, a work app that writes to ProgramData — each one is a boundary decision, not a reason to abandon the model. Resolve each case deliberately (per-user install, a specific elevated task, or documented acceptance of that one elevation) and note it, so the arrangement stays explainable. The verification habit from Tutorial 14 completes the design: occasionally confirm your daily session is still denied where it should be — the model is only as real as its refusals.

Applying Least Privilege on Shared Computers and Workstations

In this tutorial: Set sensible account boundaries on shared computers: one person per account, profile isolation, explicit shared folders, group-based access, and a review cadence.

A shared device multiplies every identity problem from the earlier categories, so the baseline rules get stricter, not looser. Rule one: one person, one account — a shared login makes actions unattributable (you cannot tell who changed what), entangles files (everyone's documents in one profile), and turns one person's compromise into everyone's. Rule two: the machine's administrative identity is separate from all user accounts and is used only for maintenance, not as a convenience login. On an office workstation this second rule collides with the common practice of making every employee a local administrator; resist it where you can, because per-user standard accounts plus scoped elevation (or IT-managed policy) keeps legacy app problems from becoming machine-wide exposure.

File boundaries follow from identity boundaries. Each user's documents live in their own profile — C:\Users\<name> on Windows, /home/<name> on Linux — and the platform defaults already keep siblings out: Linux home directories are created 700 (owner-only) by most distros' skeleton configuration, and Windows user profiles deny other users by default. The failure mode to watch is not the defaults but the erosion of them: a "so everyone can see it" folder dropped into a profile with inheritance wide open, or a home directory someone chmod 755'd years ago. Shared content gets its own explicit location and explicit permissions instead — a named shared folder whose access list says exactly who may read or write.

For legitimate sharing, groups beat per-user grants. Create a group (a family group on a home machine, a project team on a workstation), put the right people in it, and grant the group access to the shared resources. Membership is then the thing you manage and audit — adding or removing one person changes their access everywhere at once, and answering "who can see this folder" becomes reading a group list instead of decoding ten individual entries. Ties this directly into offboarding (Tutorial 10): when someone leaves, removing them from the groups is step one, before their account is disabled or deleted.

Shared machines also breed specific habits worth naming: borrowing another person's session "just to get something," leaving sessions unlocked at shared desks, and kiosk-style public use that should actually run a locked-down guest configuration rather than a real user account. Verify the arrangement both directions — attempt to open a sibling's document (should fail) and attempt to write to the shared folder from each member account (should succeed for members only). A quick cross-user test on setup day catches inheritance mistakes while they are still one command away from the fix.

Managing File, Folder, and Resource Permissions Safely

In this tutorial: Manage file, folder, and resource permissions safely - how evaluation actually works on Windows and POSIX, why membership is not access, and a systematic method for diagnosing too much or too little permission.

Permission problems are usually evaluation-order problems, so start with how each platform actually decides. On Windows NTFS, the system checks the owner's standing first, then walks the access-control entries (ACEs) on the object: explicit deny entries override any allow from any source, and entries inherited from parent folders are evaluated alongside local ones. The Security tab's Effective Access view computes exactly this result for a chosen user — use it before guessing. On POSIX systems the classic check is ordered owner → group → other: if you are the owner the owner bits decide, else if you belong to the file's group the group bits decide, else the other bits do; extended ACLs (where supported) add named-user and named-group entries on top of those three classes. Knowing the order turns "why can't I open this" into a checklist instead of a mystery.

The distinction that explains most "I'm in the group but still denied" tickets is that group membership is not access. Membership only makes the group's permission entry applicable to you; if that entry grants read, you get read — nothing more. And on both platforms, reaching a file requires traverse rights on every directory in its path: a 644 file inside a 700 parent directory is unreachable for everyone but the owner, no matter how permissive the file itself is. Windows has the same shape (traverse/read-execution on each ancestor folder), which is why "fix the file's permissions" so often does nothing — the blockage sits one level up.

Linux — project directory with group inheritance (setgid)
# Create a project dir owned by the project group; new files inherit the group.
sudo groupadd -f project-alpha
sudo mkdir /srv/projects/alpha
sudo chown :project-alpha /srv/projects/alpha
sudo chmod 2770 /srv/projects/alpha     # setgid + rwx for owner/group, none for other
# Verify:
namei -l /srv/projects/alpha            # walk the path with every directory's mode
getfacl /srv/projects/alpha             # full ACL view where extended entries exist

The setgid bit (the "2" in 2770) makes new files created inside inherit the directory's group, so a team folder does not silently fragment into per-user groups. All commands need root except the verification pair.

The Windows equivalent pattern: put shared content in one folder, grant the sharing group (not individuals) Read or Modify on that folder with inheritance enabled for children, and check Effective Access for a representative member before and after any change. When tightening, prefer adding a narrow deny or removing an over-broad inherited entry to rewriting the whole ACL from scratch — wholesale "reset permissions" operations are where working systems get broken, because they discard the history of deliberate grants.

A systematic diagnostic method works for both insufficient and excessive permissions. Start from the failing (or suspicious) operation; walk identity → group memberships → the resource's own entries → each parent directory → inheritance and explicit denies; change the narrowest layer that explains the behavior; then retest in both directions — the intended access must work and the unwanted access must still be refused. The anti-patterns to recognize on sight: recursive Full Control granted "to make it work," chmod -R 777 as a first resort, and blanket ownership changes across a drive. Each one repairs one symptom by deleting the entire permission model around it.

Temporary Privileges, Just-in-Time Access, and Administrative Boundaries

In this tutorial: Apply time-boxed administrative access and revocation discipline on a workstation, and understand where enterprise just-in-time tooling fits without being mandatory at home.

Permanent administrative membership is the default state most machines drift into, and the simplest structural correction is to make elevation temporary by construction: grant the privilege for a bounded window, do the work, remove it. On a personal computer this is manual but concrete — add your account to Administrators (or the Linux admin group) for the maintenance session, perform the updates and driver work, then run the removal command from Tutorial 06 or 07 and verify the membership is gone. The step people skip is the last one; an unverified revocation is only a promise, and "temporary" that outlives its reason becomes permanent through drift rather than decision.

Approval and separation of duties scale with the environment, and it is worth being explicit about what a workstation actually needs. At home or on a solo machine, the "approval workflow" can be a written note — what privilege, for which task, until when — that you make before granting and check off after revoking; the value is forcing the decision to happen deliberately. In an enterprise, the same discipline industrializes: privileged-access management platforms grant time-boxed elevation on request, require approval from a second role, record every elevated session, and revoke automatically at expiry. A personal computer does not need that infrastructure — presenting it as mandatory is where workstation advice goes wrong — but the sequence request → approve → time-box → audit → revoke is identical at both scales.

Revocation deserves its own checklist because it touches more surfaces than the grant did. Remove the group membership; log out of any elevated session (an open elevated PowerShell window still holds the full token); delete temporary accounts created for the task; and reset any one-time credentials issued for it. Then run the inverse verification: attempt a privileged operation from the normal identity and confirm it is refused. That refusal is the evidence the boundary is back in place — the same habit as Tutorial 14's final check, applied to the end of a window instead of the end of a task.

Documenting the boundary completes the picture. A small record per elevation event — date, identity, privilege granted, reason, scheduled end, actual end, verifier — is enough at personal scale and doubles as the baseline that Tutorial 25 compares against later. For organizations, policy-driven boundaries (Group Policy objects controlling local admin rights on domain-joined machines, for example) enforce what this tutorial does by habit; the Group Policy guide in the related section covers that side. The workstation lesson stands alone: privilege should arrive with an expiry date attached.

Category 5 · Audit and automation

Account Security, Auditing, and Automation

So far the collection has taught you to create accounts, control privilege, and set boundaries. This category turns the lens around: what is actually on the machine right now, how do you prove it, and how do you notice when it changes? Auditing here means read-only inspection with a repeatable method — the same commands every time, so that today's result can be compared against last month's. The tools are deliberately plain: PowerShell on Windows, standard utilities on Linux, and two complete scripts you can keep and re-run.

Auditing Local Users and Administrators in Windows

In this tutorial: Inventory local Windows accounts and administrative membership with read-only tools, record findings in a repeatable report format, and verify the audit itself.

A local account audit answers four questions with evidence: which accounts exist, which are enabled, which hold administrative membership, and which look wrong (unknown origin, no password required, guest access on). The method is strictly read-only — an audit that changes configuration has already failed at its job — and it must be repeatable, meaning the same commands produce comparable output next month. That repeatability is what turns a one-time cleanup into ongoing detection (Tutorial 25 builds directly on the snapshot you take here).

PowerShell — read-only local account inventory
# Accounts, enabled state and password policy (LocalUsers module: Win 10 1709+ / Server 2016+)
Get-LocalUser | Select-Object Name, Enabled, PasswordRequired, LastPasswordSet, Description

# Who is in the local Administrators group?
Get-LocalGroupMember -Group "Administrators" | Select-Object Name, PrincipalSource

# Complete list including hidden system accounts (CIM view)
Get-CimInstance Win32_UserAccount | Select-Object Name, LocalAccount, Disabled, PasswordRequired

All three commands are read-only and run without elevation. The CIM view is the superset: it includes hidden accounts (DefaultAccount, WDAG Utility Account) that the graphical tools and Get-LocalUser do not surface.

The graphical route — lusrmgr.msc on Pro/Enterprise editions, or Settings → Accounts for a lighter view — is useful for spot-checking a single account's properties, but it does not produce a record you can keep. For the record, write the findings into a fixed table: account | kind (human / service / built-in) | enabled | administrator? | password required | notes. The "kind" column matters because the right action differs by type: an unknown human-looking account is a finding; an unfamiliar system account may be a Windows feature doing its job (Tutorial 05 explains how to check dependencies before touching anything).

Flag these patterns as findings, not conclusions: an enabled Guest account; any account with PasswordRequired = False; administrative membership held by more accounts than you can name and justify; accounts whose names match nothing in your memory of who or what they belong to. Then verify the audit itself: the count from Get-CimInstance Win32_UserAccount should reconcile with what lusrmgr.msc shows plus the known hidden accounts, and every "administrator?" entry should be one you deliberately placed there. What this audit does not see is domain-side policy on a joined machine — that belongs to the Active Directory and Group Policy guides in the related section. Keep the observe phase and the change phase separate: record everything now, decide later.

Auditing Linux Users, Groups, and Privileged Access

In this tutorial: Audit Linux users, groups, and sudo capability from the files that are the source of truth - with explicit distribution differences and the limits of membership-only auditing.

On Linux the identity store is plain text, which makes auditing direct but also means you must know which file holds which fact. /etc/passwd is world-readable by design and carries username, UID, GID, home directory and login shell; /etc/shadow holds password hashes and aging data and is readable only by root; /etc/group maps groups to members. The fields that matter in an audit: UID (human accounts are 1000 or higher on most distros — lower UIDs are system/service accounts), the shell (/usr/sbin/nologin or /bin/false marks a non-login account), and, where readable, whether a password is actually set.

The privileged-access map has three layers. First, group membership in the distribution's administrative group — sudo on Debian/Ubuntu, wheel on RHEL/Fedora, admin on openSUSE — which is what lets a user run commands as root through sudo. Second, whether the root account itself has a usable password (a locked root is normal and healthy on many server configurations). Third, per-user grants in /etc/sudoers and any files under /etc/sudoers.d/, which can allow specific commands — or everything, with or without a password. Membership in one group is not universally equivalent to full administrative authority: the group name differs between families, some systems add extra rules, and polkit can grant root-equivalent operations (like disk management through a GUI) without any sudo membership at all. An audit that stops at "who is in wheel" has blind spots; say so explicitly in your report rather than pretending the membership list is the whole truth.

Bash — read-only inspection set
# Human accounts (UID >= 1000) with shell and home
getent passwd | awk -F: '$3 >= 1000 {print $1, $3, $6, $7}'

# Which administrative group exists on this distro, and who is in it?
for g in sudo wheel admin; do getent group "$g" && echo "  ^ group: $g"; done

# What can the current user run via sudo? (no root needed for own rules)
sudo -l

# Per-user grants and drop-in files (needs root to read fully)
sudo ls /etc/sudoers.d/ 2>/dev/null || echo "run with root to list sudoers.d"

Everything here is read-only. The awk filter is the standard UID-range heuristic — if your distro assigns human UIDs elsewhere, check /etc/login.defs (UID_MIN) first and adjust.

Record findings in the same fixed shape as the Windows audit so the two platforms stay comparable: user | UID | shell | groups | sudo capability | notes. Verification is arithmetic: the line count from getent passwd should equal what you expect (humans plus system accounts), every login-capable human account should be one you created or recognize, and every privileged group should have a member list you can justify out loud. Take the output as a dated snapshot — on Linux a simple > audit-YYYY-MM-DD.txt redirect is enough — because the next use of this work is comparing it against a later run.

Building a PowerShell Local Account Audit Script

In this tutorial: Build a complete, read-only PowerShell script that inventories local accounts and administrative membership, handles partial environments gracefully, and outputs a dated report.

This tutorial turns the manual commands from Tutorial 21 into one readable, repeatable script. Design goals: strictly read-only (no verb in the script can change an account), tolerant of environments where parts are missing (module absent, elevated state unknown), and output that reads as a report rather than a raw dump. Assumptions: Windows 10 version 1709 or later, or Windows Server 2016 or later, so the LocalUsers module exists; the script itself does not require an elevated prompt for its reads.

The script has four stages. First it verifies its own prerequisites and records what is available, so a partial environment produces a partial report with an explicit note instead of silent gaps. Second it inventories every local account with the properties that matter for review: enabled state, whether a password is required, when the password was last set, and where the account came from (local versus directory-sourced). Third it maps administrative membership — who is in Administrators, and which of those accounts are human rather than system. Fourth it applies a small set of flags that turn data into findings: enabled Guest, accounts with no password requirement, and admin members whose names you do not recognize.

PowerShell — uap-audit.ps1 (complete script)
#requires -Version 5.1
# uap-audit.ps1 — read-only local account & admin-membership audit
# Safe: uses only Get-* and Compare-Object; changes nothing.

$ErrorActionPreference = 'Stop'
$report = @()
$notes  = @()

# ---- Stage 1: prerequisites -------------------------------------------
if (-not (Get-Module -ListAvailable LocalUsers)) {
    Write-Warning "LocalUsers module not found. This script targets Windows 10 1709+ / Server 2016+."
    exit 1
}
$elevated = ([Security.Principal.WindowsPrincipal] `
    [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $elevated) {
    $notes += "Running without elevation: some properties may be limited."
}

# ---- Stage 2: account inventory ---------------------------------------
$users = Get-LocalUser | Select-Object `
    Name, Enabled, PasswordRequired, LastPasswordSet, PrincipalSource
foreach ($u in $users) {
    $report += [pscustomobject]@{
        Account       = $u.Name
        Enabled       = if ($u.Enabled) { 'yes' } else { 'no' }
        PasswordReq   = if ($u.PasswordRequired) { 'yes' } else { 'NO' }
        LastPassword  = if ($u.LastPasswordSet) { $u.LastPasswordSet.ToString('yyyy-MM-dd') } else { 'never' }
        Source        = [string]$u.PrincipalSource
        AdminMember   = ''
    }
}

# ---- Stage 3: administrative membership --------------------------------
try {
    $admins = (Get-LocalGroupMember -Group 'Administrators' -ErrorAction Stop) `
        | Select-Object -ExpandProperty Name
} catch {
    $notes += "Could not read Administrators membership: $($_.Exception.Message)"
    $admins = @()
}
foreach ($name in $admins) {
    $row = $report | Where-Object { $_.Account -eq $name }
    if ($row) { $row.AdminMember = 'yes' }
    else { $notes += "Admin member '$name' not found in Get-LocalUser (system or hidden account)." }
}

# ---- Stage 4: findings --------------------------------------------------
$findings = @()
foreach ($r in $report) {
    if ($r.Account -eq 'Guest' -and $r.Enabled -eq 'yes')        { $findings += "Guest account is enabled." }
    if ($r.PasswordReq -eq 'NO' -and $r.Enabled -eq 'yes')       { $findings += "'$($r.Account)' has no password requirement and is enabled." }
}

# ---- Output --------------------------------------------------------------
Write-Host "== Local account audit — $(Get-Date -Format 'yyyy-MM-dd HH:mm') =="
$report | Format-Table -AutoSize | Out-String | Write-Host
if ($findings.Count) {
    Write-Host "FINDINGS:" -ForegroundColor Yellow
    $findings | ForEach-Object { Write-Host "  - $_" }
} else {
    Write-Host "No automatic findings. Review the table for unknown accounts."
}
foreach ($n in $notes) { Write-Host "note: $n" -ForegroundColor DarkGray }

The script is intentionally conservative: every external call is a Get-* cmdlet, the only exit path on failure reports what is missing, and nothing it prints can be mistaken for an action it took.

Run the script from a normal (non-elevated) PowerShell window to prove the read-only claim in practice: save it as uap-audit.ps1, then execute powershell -ExecutionPolicy Bypass -File .\uap-audit.ps1. The -ExecutionPolicy Bypass flag applies only to that one invocation and does not change your machine's policy; an equivalent alternative is running Set-ExecutionPolicy -Scope Process Bypass inside the same window first, which expires when the window closes. Correct output is a table whose rows match what lusrmgr.msc shows, an empty or populated FINDINGS section, and any environment notes at the bottom. Verify one row by hand: pick an account, run Get-LocalUser -Name "ThatAccount", and confirm the Enabled and PasswordRequired values agree.

Two limitations are worth stating before you rely on this. First, Get-LocalUser enumerates ordinary local accounts; hidden system identities such as DefaultAccount appear in the CIM class instead, so a thorough audit cross-references Get-CimInstance Win32_UserAccount and notes the difference — the script's Stage 3 already flags admin members that Get-LocalUser cannot see. Second, the report is a snapshot: it proves what was true at run time, not how long it has been true (Tutorial 25 covers turning snapshots into change detection). To keep records, append one line to the script: $report | Export-Csv -Path "$env:USERPROFILE\account-audit-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation — still read-only with respect to the system, and it gives you dated artifacts for comparison.

Building a Bash Account and Group Audit Script

In this tutorial: Build a practical Bash audit script for Linux account and group information with command-availability checks, graceful handling when root is unavailable, and snapshot output.

The Linux equivalent of the previous script has different constraints, because there is no single blessed enumeration API: the plain text files under /etc are the source of truth on virtually every mainstream distribution. The script therefore uses only universally present tools — getent, id, and basic text utilities — checks that each exists before relying on it, and degrades gracefully where access is limited: a non-root user cannot read /etc/shadow, so the script reports password state as "not visible without root" instead of failing or guessing.

The report has three sections. Human accounts lists every account with a UID at or above the human range (1000 on most distributions; configurable via a variable), showing shell and home directory — accounts with no login shell are marked, since those are typically service identities that deserve separate review (Tutorial 05). Group memberships shows each user's full group set, which is where privilege actually lives. Privileged access then names the administrative groups that exist on this system (sudo, wheel, admin — whichever are present) with their members, and lists any files under /etc/sudoers.d/ if readable.

Bash — read-only audit script (mainstream distributions)
# uap-audit.sh — local account & group audit, read-only.
# Usage: bash uap-audit.sh          (works without root; shadow fields need root)
HUMAN_UID_MIN=1000   # adjust if your distro differs

for tool in getent id awk sort; do
  command -v "$tool" >/dev/null || { echo "ERROR: required tool missing: $tool"; exit 1; }
done

echo "== HUMAN ACCOUNTS (uid >= $HUMAN_UID_MIN) =="
getent passwd | awk -F: -v min="$HUMAN_UID_MIN" '$3 >= min {
  shell=$7; flag=(shell ~ /nologin|false$/) ? " [no-login-shell]" : ""
  printf "%-20s uid=%-6s home=%-28s shell=%s%s
", $1, $3, $6, shell, flag
}'

echo
echo "== GROUP MEMBERSHIPS =="
getent passwd | awk -F: -v min="$HUMAN_UID_MIN" '$3 >= min {print $1}' | while read -r u; do
  printf "%-20s %s
" "$u" "$(id -nG "$u" 2>/dev/null || echo 'lookup failed')"
done

echo
echo "== PRIVILEGED GROUPS =="
for g in sudo wheel admin; do
  if getent group "$g" >/dev/null; then
    printf "%-8s members: %s
" "$g" "$(getent group "$g" | cut -d: -f4)"
  fi
done

echo
echo "== SUDOERS DROP-IN FILES =="
if [ -r /etc/sudoers.d ] && [ -d /etc/sudoers.d ]; then
  ls -1 /etc/sudoers.d/ 2>/dev/null | sed 's/^/  /' || true
else
  echo "  (not readable without root — re-run with sudo to list)"
fi

echo
if [ -r /etc/shadow ]; then
  echo "== ACCOUNTS WITH EMPTY PASSWORD FIELD (no password set) =="
  awk -F: '($2 == "" && $1 !~ /^(nobody|daemon|bin)$/){print "  "$1}' /etc/shadow
else
  echo "(shadow file not readable — password state needs root)"
fi

Read-only: the script performs no modification. The only privilege-sensitive part is reading /etc/shadow and listing /etc/sudoers.d, which it handles by reporting unavailability rather than failing.

Run it with bash uap-audit.sh from any terminal; for the full report use sudo bash uap-audit.sh. Verify the output against manual checks: pick one user and compare the script's group list with id -nG username, and confirm the human-account count matches getent passwd | awk -F: '$3 >= 1000' | wc -l. A correct run ends without errors even when parts are unreadable — that graceful degradation is a feature, because you will usually first run this as an ordinary user.

The script's assumptions deserve the same honesty as the PowerShell one: it treats "human" as UID-based (documented and configurable), it does not parse /etc/sudoers itself (only lists drop-in files — parsing sudoers syntax is error-prone and unnecessary for an inventory), and it says nothing about polkit rules or capabilities, which can grant privileged operations without group membership. For a dated record, run sudo bash uap-audit.sh | tee "audit-$(date +%Y%m%d).txt"; those timestamped files are the baseline that Tutorial 25 diffs against.

Detecting Unexpected Administrator Membership and Account Changes

In this tutorial: Establish an account baseline, detect unexpected administrator membership and account changes by diffing snapshots, and know what log evidence exists - and does not exist - to explain them.

"Unexpected" is only meaningful against a baseline, so this tutorial starts there: run the audit from Tutorial 23 (Windows) or 24 (Linux), save the output with a date, and keep it somewhere you will still have it next month — a notes file on another device is better than the machine being audited, in case the change came from that machine. The baseline is not perfection; it is simply the state you understood and accepted.

The detection workflow is a diff with triage attached. Re-run the identical audit command, save the new snapshot, and compare — diff old.txt new.txt on Linux or Compare-Object (Get-Content old.txt) (Get-Content new.txt) in PowerShell for line-level differences. Then categorize every delta before reacting: a new local account, an administrative group membership change, an enabled/disabled flip, a shell change (Linux), or a password reset. Categories carry different urgency: a new member of Administrators or the sudo group is an incident until someone who made that change can be found; a new standard account might be a family member you forgot to note. The triage table keeps the emotional response proportional to the finding.

Triage categories for account-change findings: severity and first action
Finding categoryTypical severityFirst action
New local administrator / sudo memberHigh — incident until explainedFind who/what made the change (event log, journal); disable the account if unexplained
Unknown new standard accountMediumCheck creation time and first logon; ask household/office; remove if unaccounted
Account disabled or re-enabledContext-dependentVerify against your own offboarding/onboarding records (Tutorial 10)
Shell changed to a login shell (Linux)High for no-login accountsInspect the account's purpose; revert if unexplained
Password reset without recordMedium–highCheck authentication logs for the reset event and source

Evidence about when and by whom lives in the audit trails, which is where snapshot-based detection has its limit: a diff tells you state changed between two dates, not who did it or exactly when. On Windows, the Security log records account lifecycle events by default on Windows 10/11 — 4720 (account created), 4726 (deleted), 4728 and 4732 (added to / removed from a local group), 4756 (group disabled). Query them with Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4720 or EventID=4726 or EventID=4728 or EventID=4732)]]" -MaxEvents 50, or browse in eventvwr.msc under Windows Logs → Security. On Linux, journalctl (or auth.log on Debian-family systems) captures the actual useradd/usermod/gpasswd invocations and every sudo use; persistence of those logs across reboots depends on journal configuration, which is worth verifying if you rely on it. A machine with logging disabled is worse than one with no baseline at all — you cannot reconstruct what happened.

The practical cadence follows exposure: a personal single-user machine can audit monthly with a five-minute diff; a shared workstation deserves the same check weekly, because "someone else's" change is your problem within hours. When a finding stays unexplained after checking logs and asking people, stop treating it as misconfiguration — an unexplained local administrator is the signature of compromise, and the correct next destination is the site's security guide on suspicious behavior rather than any account tutorial. The discipline that makes all of this work is boring on purpose: same commands every time, dated snapshots, and a triage table applied before judgment.

Category 6 · Troubleshooting, hardening & verification

Troubleshooting, Hardening & Verification

The last category turns the model into muscle memory: diagnosing access failures at the layer that is actually failing, hardening the local account surface on each platform, and closing the loop with a complete review you can repeat. The diagnostic tutorials here deliberately resist the two universal shortcuts — sudo on Linux and Full Control on Windows — because both convert a diagnosable problem into a permission model you no longer understand.

Diagnosing Linux Permission Denied Errors Without Using Root

In this tutorial: Diagnose Linux permission-denied errors without reaching for sudo: identity, ownership, permission bits, directory traversal, and ACLs in a fixed order, with the safe fix options at each step.

"Permission denied" is a verdict, not a mystery — the kernel checked your identity against the path and found no matching grant. The diagnostic sequence below works entirely as your normal user, in this order: (1) confirm who you are with id, (2) inspect the target's ownership and bits with ls -l, (3) inspect every directory in the path with namei -l /path/to/file, and (4) check extended ACLs with getfacl if the first three don't explain it. Each step eliminates a whole class of causes, so you stop at the one that does.

Step 3 is where most diagnoses go wrong, because the traversal rule surprises people: to reach a file you need execute (traverse) permission on every parent directory, no matter what the file's own bits say. If /home/bob is mode 700 and alice tries to read /home/bob/shared/notes.txt — a perfectly readable 644 file — she is denied at /home/bob, and staring at the file's bits will never explain it. namei -l prints the mode of each path component, so the blocked directory jumps out immediately; that single command answers "where in the path am I stopped?" better than any amount of theorizing.

Reading the target itself is then mechanical. From ls -l: the owner (first name) and group (second name), followed by nine bits in owner/group/other triplets, plus special bits — setuid on executables, the sticky bit on shared directories like /tmp. Worked example: a project directory shown as drwxrws--- root devteam (mode 2770) means root owns it, the group is devteam, members of devteam get full access, and everyone else gets nothing — the setgid bit additionally makes new files inside inherit the devteam group, which is how shared project directories stay consistent. If you are in devteam and still denied, the cause is no longer the base bits: run getfacl on the directory and look for explicit ACL entries (including mask::---, which can silently cap every group grant) before concluding anything.

The fix ladder runs narrowest first, and each rung must be retested in both directions. Rung one: join the owning group — a single auditable membership change made by an administrator (sudo usermod -aG devteam alice, effective at next login per Tutorial 09). Rung two: ask the owner to adjust exactly one entry — chmod g+r on one file, or a targeted setfacl grant — rather than reopening the whole directory. Rung three: if the path is genuinely shared, fix the parent chain's modes so traversal works for the intended people. The two reflexes this ladder exists to prevent: reaching for sudo (which papers over the real cause and trains you to stop reading errors), and "just chmod 777 it" or a recursive chmod -R, which deletes the boundaries you were trying to understand and creates fresh denials — and exposures — for every other user on the box. If all four checks show the owner deliberately withheld access, the error is working as designed: the correct next step is talking to the owner, not bypassing them.

Diagnosing Windows Access Denied and Ownership Problems

In this tutorial: Investigate Windows access-denied and ownership problems using the Security tab, explicit denies, inheritance, ownership, and the Effective Access tool - without recursive Full Control.

Before touching a single permission, separate the three causes that all surface as "Access is denied": a missing allow (nothing grants you this), an explicit deny (something actively forbids it — denies beat every allow in NTFS evaluation), or elevation/integrity protection (the operation needs more than your token carries, including the protected system directories that resist even administrators). Where the denial was reported matters: Explorer's dialog, a PowerShell exception on Get-Item, or an application log each point at slightly different layers, and an administrator denied on C:\Windows\System32 is usually integrity-level behavior, not an ACL gap — the honest answer there is "this path is protected by design," not a permission to hunt.

The investigation sequence runs in this order. (1) Confirm identity and groups: net user %username% or the Tutorial 21 inventory — you cannot reason about grants to an identity you have misidentified. (2) Open the resource's ACL (Properties → Security → Advanced) and scan for explicit Deny entries first, because a deny on this folder or any ancestor explains everything downstream. (3) Check inheritance: each ACE shows whether it is inherited from a parent; a local deny sitting on one subfolder is exactly what produces "it works everywhere except here." (4) Look at ownership — who owns the object, and remember the owner's special standing to modify its ACL even without Full Control (Tutorial 03). (5) Use the Advanced Security dialog's Effective Access tab: it computes precisely what your identity ends up with after all allows, denies and inheritance are applied. Run that computation before changing anything — it converts the diagnosis from guessing into reading.

Ownership problems form their own class, usually with a recognizable signature: files whose owner field shows a bare security identifier (S-1-5-21-…) instead of a name are orphaned objects left behind by a deleted account (Tutorial 03 covered the mechanism). Taking ownership of one such object is a normal, targeted operation — Advanced → Owner → Change, select your account, check "Replace owner on subcontainers and objects" only if the scope genuinely requires it. The anti-pattern to refuse is the reflexive "take ownership of the whole drive and grant myself Full Control recursively": that rewrites thousands of ACEs, flattens every deliberate boundary someone set up, and can break services that depend on exact permission shapes. If you find yourself wanting that button, stop — the correct question is which specific objects are actually failing, and what each one needs.

The fix ladder mirrors Tutorial 26's philosophy: make the narrowest change that suffices, then retest in both directions. Grant one account or group one permission on one folder, with inheritance enabled only where you intend the grant to flow; fix ownership on the specific orphaned file rather than its parent tree; verify no explicit deny is silently shadowing your new allow (Effective Access again). When the real gap turns out to be elevation — a standard user hitting a protected system path — the correct conclusion is "this operation requires administrator," and the right move is elevating just that task per Tutorial 14 rather than promoting the account. Document each change you make (what, where, why) so the next diagnosis starts from a map instead of fog.

Securing Local Accounts on a Windows Computer

In this tutorial: Work through a prioritized hardening checklist for local Windows accounts - unknown accounts, administrative membership, password state, elevation hygiene, updates, recovery - verifying each item.

This checklist is prioritized, not parallel: work top to bottom, and each item pairs the action with its verification so you can prove the state changed rather than assume it. Run the Tutorial 21 audit first — the checklist tells you what a good state looks like; the audit tells you where you currently are. Do one section per sitting; the changes are individually small but cumulative, and verifying as you go keeps any problem attributable to the item that caused it.

A — Account surface. Remove or disable every account the audit flagged as unknown (disable first, observe a week, then delete if nothing breaks — Tutorial 10's offboarding procedure). Confirm Guest is disabled (net user Guest should report the account is disabled; it is by default on Windows 10/11 — leave it that way). Check the built-in Administrator: on consumer machines it is disabled by default, which is the state to keep; if you have enabled it for a repair, return it to disabled once the repair is done. Do not rename the built-in Administrator as "security" — renaming obscures audits without stopping anyone who reads the SID.

B — Administrative membership. net localgroup Administrators should list exactly the people (and no more) who need system-wide control. Remove members you cannot name a current reason for — including accounts that software installers quietly added; re-run the audit after any major install, because installer-driven admin grants are a recurring real-world source of bloat. If your daily account is an administrator, the checklist's most valuable item is structural: adopt the Tutorial 17 model and move routine work to a standard account.

C — Passwords & sign-in. Every active account must require a password (Settings → Accounts → Sign-in options, or net user output showing no blank password); PINs are a fine convenience layer on top of a password, never a substitute for one. Turn on "Require sign-in on resume" so an unlocked walk-away does not become someone else's session. Local administrator password rotation (LAPS-style) is an enterprise domain topic — noted here only so you recognize it as out of scope for a standalone PC.

D — Elevation hygiene. UAC stays at its default notification level; the check is reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA returning 0x1, and ConsentPromptBehaviorAdmin at 2 or 5 (Tutorial 12). Audit applications that force elevation: right-click each suspicious program → Properties → Compatibility, and remove the "Run this program as an administrator" tick where it was not deliberately set. Then review scheduled tasks running with highest privileges — taskschd.msc or Get-ScheduledTask | Where-Object {$_.Principal.RunLevel -eq 'Highest'} — because a task that auto-elevates is an elevation path you did not choose at the moment it fires.

E — Updates & recovery. Keep Windows Update current — account and authentication security features ship through updates, so an unpatched machine silently re-opens older gaps. Test your recovery path while you are locked in: confirm you can actually reset a forgotten password (security questions or the Microsoft account flow) — the site's passwords & accounts recovery guide covers each path — and keep account credentials in a password manager so "lost admin password" never becomes an unrecoverable state. The three things this checklist deliberately does not do: disable UAC, enable Guest "just for testing," or create a second administrator as a backup — a backup is a documented recovery procedure, not another privileged identity.

Securing Local Accounts on a Linux Computer

In this tutorial: Run a distribution-aware hardening workflow for local Linux accounts: account surface, privileged groups, sudo policy, authentication files, service identities, and logging.

The same five-section shape as the Windows checklist, translated to POSIX — with an explicit note wherever an item depends on distribution, because the group names, file layouts and defaults genuinely differ. Start from the Tutorial 22 audit; each section below states its verification so "done" means "checked," not "ran a command once."

A — Account surface. No unknown human accounts: getent passwd filtered to uid ≥ 1000 should list only people you can name, each with a deliberate shell. Service and system accounts (uid < 1000) should carry non-login shells — spot-check with getent passwd | awk -F: '$3<1000 {print $1, $7}' and confirm anything with a real shell has a reason. Check for duplicate UIDs, the classic silent identity collision: getent passwd | cut -d: -f3 | sort -n | uniq -d should print nothing. Verify no human account has an empty password field — as root, passwd -S <name> reports Locked/P for each user; a "P" with no aging on an account nobody uses is a finding.

B — Privileged groups & sudo grants. Membership in the privileged group (sudo on Debian/Ubuntu, wheel on RHEL/Fedora, admin on openSUSE — check which one your distro actually uses) should be minimal and named. Then go beyond membership: list /etc/sudoers.d/ and read every file in it, because per-user grants and especially NOPASSWD entries live there and are invisible to a group-membership-only audit (Tutorial 22's blind-spot warning). A deliberate root password policy is the third piece: many desktop distros lock the root account and route everything through sudo — if yours is unlocked with a weak or shared password, that is your highest-priority finding.

C — Authentication & file hygiene. Password aging should reflect intent: passwd -S shows last change and expiry per user; set sensible minimums rather than trusting defaults you never chose. The shadow file itself must stay private — ls -l /etc/shadow should show 640 owned by root (group shadow on Debian-family); world-readable hashes are a critical finding, not a curiosity. If any user uses SSH keys: their .ssh directory at 700 and authorized_keys at 600 — looser modes make sshd refuse the keys or, worse, let others append to them.

D — Services & logging. Every long-running service should run as a named low-privilege user rather than root: systemctl list-units --type=service --state=running plus systemctl show <unit> -p User (or the unit file's User= line) reveals which daemons are sitting at maximum privilege — each root daemon is a standing elevation target if compromised (Tutorial 05). Make the audit trail durable: journald should store persistently (Storage=persistent in a /etc/systemd/journald.conf.d/ drop-in, or your distro's default), and a quick journalctl -b | grep -i logind | head confirms authentication events are actually being recorded — without durable logs, the Tutorial 25 detection workflow has no evidence to work from.

E — Lifecycle & distribution notes. Close with the process items: an offboarding procedure exists (Tutorial 10), home directories are not world-readable (ls -ld /home/* showing 700 or 750), and the next audit date is written down. What genuinely varies by distro: the privileged group's name, where sudoers lives beyond /etc/sudoers.d/, default shadow-utils behavior, and polkit rules that can grant root-equivalent actions to non-members — which is why this checklist says "check your distro's actual configuration" at each step instead of asserting a universal answer. The verification habit carries over from the Windows version: every item above ends with a command whose expected output you have already read, so completion is evidence, not intention.

Conducting a Complete Least-Privilege Review and Remediation

In this tutorial: Conduct an end-to-end least-privilege review: scope, inventory, privilege inspection, needs mapping, prioritized findings, reversible fixes, retesting of real workflows, and a final-state document.

This tutorial runs the whole collection as one procedure. Before touching anything, write the scope in two sentences: which machine, who legitimately uses it, and what it is for — a home box with two people and a work laptop have different correct answers, and skipping this step is how reviews drift into changing things that should not change. The review has seven stages, each producing a concrete artifact; you do not advance until the current stage's artifact exists, because every later stage consumes it.

  1. Inventory identities. Run the Tutorial 23 (Windows) or 24 (Linux) audit and save a dated snapshot. Artifact: the baseline file.
  2. Inspect privileges. From the baseline, extract every elevation path: administrative group members, sudo/sudoers.d grants, service accounts with login shells, scheduled tasks or cron jobs running elevated. Artifact: one line per identity — what it can do beyond its stated job.
  3. Map actual need. For each identity, list the real tasks performed on this machine in the last month — by observation or conversation, not assumption. A "backup admin" who has not installed anything in a year needs no permanent admin rights. Artifact: need-per-identity, two lines each.
  4. Identify excess. Diff granted against needed. Every finding gets severity (who is exposed if this identity fails), an owner, and a proposed fix — disable vs remove vs re-scope. Artifact: the findings table.
  5. Prioritize. Administrative excess first (it multiplies every other risk), then shared-account exposure, then over-broad resource permissions. Resist the urge to fix cosmetic items before structural ones. Artifact: an ordered worklist.
  6. Implement reversible fixes. One change at a time, each with its rollback command written down before you run it — removing someone from Administrators rolls back by re-adding; disabling an account rolls back by re-enabling (Tutorial 10's disable-before-delete rule is load-bearing here). Artifact: the change log, entry per fix.
  7. Retest & document. Walk each user through their five most common tasks; re-run the audit and diff against the baseline — that diff is your changelog. Write the one-page final-state record: what each identity can do now, who decided it, how to roll anything back, and the date of the next review. Artifact: the final-state document.

Stage 7's retest deserves its own discipline because it is where reviews die: a fix that breaks a workflow is not a fix, it is a new problem with an owner who did not consent to it. When a task genuinely cannot work without more privilege, do not silently restore the old grant — record a deliberate exception ("this installer requires elevation; scoped to this app, reviewed quarterly"), because an undocumented exception is just drift wearing a costume. The final-state document is the actual deliverable of the whole exercise: it answers "what can each identity do on this machine, and who decided," which is the only thing the next person — or future you — can inherit. Without it, unrevoked temporary privileges quietly become permanent ones within a month, and the review's value decays to zero.

Two boundaries keep this procedure honest. First, it stops where the machine ends: domain policies, GPOs and enterprise privileged-access systems are a different discipline (the site's Active Directory and Group Policy guides cover that side), and malware-driven findings belong in the security guide, not a permissions review. Second, a single perfect review is worthless without cadence — schedule the next one in the final-state document itself, and let the monthly diff workflow from Tutorial 25 be the early-warning system between reviews. The loop is the point: inventory, inspect, compare to need, fix reversibly, retest, document, repeat.

Glossary

Short definitions for the terms used throughout the 30 tutorials. Where a tutorial explains a term in depth, it is linked.

Local account
An identity stored on and valid for a single computer only - its name, password (or hash), groups, and profile live in that machine’s own databases. Tutorials 01 and 04.
Security identifier (SID)
Windows’ unique, immutable identifier for a user or group. Permissions bind to SIDs, not names - which is why renaming an account keeps its access, and deleting one can orphan it. Tutorial 03.
User ID / Group ID (UID/GID)
Unix-like systems’ numeric identity for users and groups. UID 0 is root; human accounts normally start at 1000. Names in /etc/passwd are a lookup layer over these numbers. Tutorials 03 and 07.
Group membership
The set of groups an identity belongs to. Primary group plus supplementary groups on Unix; local group membership on Windows. Membership grants only what the group’s permission entries actually say. Tutorials 09 and 19.
Ownership
The single user (or, on Windows, a special owner role) attached to an object that can typically change its permissions even when they have no ordinary access to it. Tutorial 19.
Effective access
What an identity can actually do on a resource after all rules are evaluated - membership, explicit allows and denies, inheritance, and elevation state combined. The number that matters in every access-denied ticket. Tutorials 19 and 27.
Elevation
Deliberately running one task with higher privileges than the current session holds: a UAC prompt on Windows, a sudo prefix on Linux. The opposite of “running everything elevated.” Tutorials 12-14.
UAC (User Account Control)
Windows’ mechanism that filters an administrator’s token by default and asks for consent or credentials when a task needs the full one. Tutorial 12.
sudo
The standard Unix-like tool for running a single command as another user (usually root), governed by policy files and logged. Tutorial 13.
Least privilege
Giving each identity only the permissions its task requires - in scope, operation, and duration - so mistakes and compromise have a small blast radius. Explained fully in Tutorial 16; applied everywhere else.
Just-in-time access
Granting elevated rights for a bounded window with a defined end, then revoking them. On a personal computer this is manual discipline; in enterprises it is usually automated tooling. Tutorial 20.
Trust boundary
The edge of what one identity or system can be assumed to protect. A local account’s boundary is its own machine - nothing on this page changes what a domain policy or another computer decides. Tutorials 04 and 16.

Frequently asked questions

Do I need an administrator account to use my computer day to day?

No. On both Windows and Linux, everyday work - browsing, documents, media, most application installs that support per-user mode - runs fine with a standard (non-admin) account. Administrative rights are needed for a smaller set of tasks: system-wide software installation, driver changes, user management, and security settings. Tutorials 11, 14, and 17 sort out which is which.

Is it safer to turn off UAC or stop using sudo prompts?

No - those prompts are the control working. Disabling them removes the moment where an unexpected elevation request can be noticed and refused, which is exactly the situation the prompts exist for. If prompts feel excessive, the fix is finding which application requests elevation and why (Tutorial 12), not removing the question.

Can I just grant Full Control or run chmod 777 to stop getting access errors?

You can, and you will stop getting that particular error - while creating a permission model where anyone (or any compromised process) can read, change, or delete the resource. Both are the classic shortcuts this collection repeatedly warns against. The diagnostic path in Tutorials 26 and 27 finds the specific missing grant and adds only that.

What is the difference between my local account and my Microsoft or online account?

A local account lives only on one machine; an online identity authenticates against a service and can sign in to many devices, with recovery and policy handled by that service. On Windows the two can be mixed - a sign-in identity and the local permissions it carries are separate things. Tutorial 04 covers the trade-offs; Tutorial 01 defines the terms.

How often should I audit the accounts on a personal computer?

A practical rhythm is one full audit per month using the scripts in Tutorials 23 or 24, compared against the previous snapshot (Tutorial 25). After any event that changes accounts - a new family member, a new service install, suspected tampering - run it immediately. The audit is read-only and takes minutes.

Will removing myself from the Administrators group break my applications?

Usually not - most consumer software runs fine per-user, and the tasks that genuinely need elevation can be elevated individually (Tutorial 14). The right order is: move to a standard account, live with it for a week, list every task that fails, then decide per task whether it deserves deliberate elevation or a different install mode. Tutorial 17 walks through this transition.