MacOS
View all Worklets
MacOSmacOS

Enforce Password Complexity

Enforce macOS password complexity by writing a pwpolicy account policies plist for every local user in one pass

Worklet Details

What the macOS password complexity enforcer does

This Automox Worklet™ enforces a password complexity baseline on macOS endpoints by writing a pwpolicy account policies plist for every local user with a UniqueID of 500 or higher. The Worklet reads nine policy variables from the script header, queries each account's current policy with sudo pwpolicy -u <user> -getaccountpolicies, and rewrites the plist when any of those policy lines are missing or do not match the configured values.

The defaults shipped in the script are MAX_FAILED=5, LOCKOUT=120 seconds, PW_EXPIRE=90 days, MIN_LENGTH=10, MIN_NUMERIC=2, MIN_ALPHA_LOWER=2, MIN_UPPER_ALPHA=2, MIN_SPECIAL_CHAR=3, and PW_HISTORY=3. Account enumeration uses dscl . list /Users UniqueID filtered to UID >= 500, so system accounts created below that boundary are skipped automatically. One configurable exempt account is supported through the exemptAccount1 variable, which must be set away from the placeholder ENTER_EXEMPT_ACCOUNT before scheduling.

After each per-user plist is applied, the Worklet runs sudo pwpolicy -setglobalpolicy "newPasswordRequired=1" so every affected user is prompted for a new password that satisfies the baseline at next login. Because pwpolicy is the supported macOS API for local-account password policy, the change persists across reboots without an MDM profile.

Why enforce a password baseline on every Mac

Weak local passwords remain the path of least resistance into a Mac endpoint. A user who picks a six-character pet name defeats FileVault, Touch ID fallback, and every Screen Sharing control behind it. CIS Benchmark macOS section 5 (password strength) and PCI-DSS 8.3.6 both require a minimum length plus character-class enforcement. HIPAA's Security Rule at 164.308(a)(5)(ii)(D) calls for documented password management and lockout protections without prescribing specific values, so organizations document their baseline here and reuse it as audit evidence.

A laptop reissued from a hardware refresh, a developer account created locally to run a build, or an admin who cleared the policy plist with pwpolicy -clearaccountpolicies will all leave the baseline silently broken. The pwpolicy -getaccountpolicies check runs on every evaluation, and the Worklet rewrites the plist when it finds the length, character-class, history, expiration, or lockout values out of spec, so the regression never matures into an audit finding.

How macOS password policy enforcement works

  1. Evaluation phase: The Worklet validates PW_EXPIRE is greater than zero, then enumerates local users with dscl . list /Users UniqueID and filters to UID >= 500, skipping the configured exemptAccount1. For each remaining user, it runs sudo pwpolicy -u <user> -getaccountpolicies and greps for the literal policy lines that correspond to PW_HISTORY, MIN_SPECIAL_CHAR, MIN_UPPER_ALPHA, MIN_ALPHA_LOWER, MIN_NUMERIC, MIN_LENGTH, PW_EXPIRE, LOCKOUT, and MAX_FAILED. If any line is missing or mismatched, the script exits 1 and the evaluation log shows which control failed on which account.

  2. Remediation phase: The Worklet rebuilds the account policy plist at /private/var/tmp/pwpolicy.plist with policyCategoryAuthentication, policyCategoryPasswordChange, and policyCategoryPasswordContent sections, chmod 777 on the file, then runs sudo pwpolicy -u <user> -clearaccountpolicies followed by sudo pwpolicy -u <user> -setaccountpolicies /private/var/tmp/pwpolicy.plist for each non-exempt user. Once the loop finishes, sudo pwpolicy -setglobalpolicy "newPasswordRequired=1" forces a password reset at next login. The script then exits 0.

macOS password policy requirements

  • macOS on Intel or Apple silicon with pwpolicy and dscl available (both ship with every supported macOS release)

  • Root or sudo context for pwpolicy and dscl, which the Automox agent already runs under by default

  • Local-only authentication; endpoints bound to Active Directory, Jamf Connect with an IdP, or Kerberos rely on the directory service for password policy and should be excluded from this Worklet (the script header carries the same warning)

  • Set the policy values in the script before scheduling: MAX_FAILED, LOCKOUT (seconds), PW_EXPIRE (days, must be greater than 0), MIN_LENGTH, MIN_NUMERIC, MIN_ALPHA_LOWER, MIN_UPPER_ALPHA, MIN_SPECIAL_CHAR, and PW_HISTORY

  • Replace the exemptAccount1="ENTER_EXEMPT_ACCOUNT" placeholder with the username of a service or remote-management account (for example a Jamf or break-glass admin); only one exempt account name is supported

  • Communicate the change to end users before scheduling, because every non-exempt local user with UID >= 500 will be forced to set a new password at next login

Expected state after macOS password enforcement

After remediation, every non-exempt local account with UID >= 500 carries the configured baseline. Running sudo pwpolicy -u <username> -getaccountpolicies returns a plist with the policyCategoryAuthentication block (autoEnableInSeconds at LOCKOUT, policyAttributeMaximumFailedAuthentications at MAX_FAILED), the policyCategoryPasswordChange block (policyAttributeExpiresEveryNDays at PW_EXPIRE), and a policyCategoryPasswordContent block containing minimumLength, minimumNumericCharacters, minimumAlphaCharactersLowerCase, minimumAlphaCharacters, minimumSymbols, and policyAttributePasswordHistoryDepth at the configured values. The next login prompts the user to set a new password because the global newPasswordRequired flag is set, and macOS rejects any candidate that fails one of the policyAttributePassword regex checks at the password sheet.

Subsequent Automox policy runs report the endpoint as compliant without rewriting the plist, because the evaluation phase finds every expected policy line present. For audit evidence, capture the output of sudo pwpolicy -u <username> -getaccountpolicies alongside the Automox activity log entry for the policy run. If an administrator clears the policy with sudo pwpolicy -u <user> -clearaccountpolicies, the next evaluation flags the endpoint and the remediation phase reinstalls the plist on the affected user.

View in app
evalutation image
remediation image

Consider Worklets your easy button

What's a Worklet?

A Worklet is an automation script, written in Bash or PowerShell, designed for seamless execution on endpoints – at scale – within the Automox platform. Worklets deploy named-CVE mitigations within hours of disclosure, perform configuration, remediation, and install or remove applications and settings across Windows, macOS, and Linux.

do more with worklets