Commit fa25287458

fa252874584e7590c487014ad490d0ea6580bfcb

parent: 7fc78c7190

Unregistered key

cmc <hello@cleberg.net> · 2026-02-22 06:19 UTC
committer: <noreply@github.com>

fix formatting of latest post (#14)

Layout: unified · split

content/blog/2026-02-21-auditing-aws-passwords.org +26 −22
@@ -29,11 +29,12 @@ testing.
29 29
30The process runs in two steps: 30The process runs in two steps:
311. ~gather_policy.sh~ calls the AWS CLI to fetch the current IAM password policy, 311. ~gather_policy.sh~ calls the AWS CLI to fetch the current IAM password policy,
32captures metadata (timestamp, AWS account, region, caller identity), and writes 32 captures metadata (timestamp, AWS account, region, caller identity), and
33everything to a JSON file. This file is evidence of the policy's current state. 33 writes everything to a JSON file. This file is evidence of the policy's
342. ~evaluate_policy.py~ reads that JSON file, prompts you for the expected value of 34 current state.
35each setting, and exports a CSV report with a value of ~PASS~ or ~FAIL~ for each 352. ~evaluate_policy.py~ reads that JSON file, prompts you for the expected value
36rule. 36 of each setting, and exports a CSV report with a value of ~PASS~ or ~FAIL~ for
37 each rule.
37 38
38* Prerequisites 39* Prerequisites
39 40
@@ -182,32 +183,35 @@ allows you to prove that the data was not modified after the script was run.
182* Common Exceptions and False Positives 183* Common Exceptions and False Positives
183 184
184- *No policy defined*: If ~gather_policy.sh~ exits with a ~NoSuchEntity~ error, the 185- *No policy defined*: If ~gather_policy.sh~ exits with a ~NoSuchEntity~ error, the
185account has no IAM password policy configured. If you were expecting a password 186 account has no IAM password policy configured. If you were expecting a
186policy, document it as a missing control. 187 password policy, document it as a missing control.
187- *HardExpiry: false*: This setting controls whether users are locked out 188- *HardExpiry: false*: This setting controls whether users are locked out
188immediately when their password expires or given a grace period to change it. 189 immediately when their password expires or given a grace period to change it.
189~false~ is often intentional to avoid lockouts. Check the organization's policy 190 ~false~ is often intentional to avoid lockouts. Check the organization's policy
190before calling it a finding. Additionally, check if the organization has 191 before calling it a finding. Additionally, check if the organization has
191security exceptions in place before noting a deficiency. 192 security exceptions in place before noting a deficiency.
192- *MaxPasswordAge and forced rotation*: A 90-day rotation requirement is common in 193- *MaxPasswordAge and forced rotation*: A 90-day rotation requirement is common in
193older policies and frameworks like CIS. NIST 800-63B no longer recommends forced 194 older policies and frameworks like CIS. NIST 800-63B no longer recommends
194rotation unless there's evidence of compromise. Know which framework you're 195 forced rotation unless there's evidence of compromise. Know which framework
195auditing against before writing up a finding for this setting. Confirm with the 196 you're auditing against before writing up a finding for this setting. Confirm
196organization to understand which framework they used to write their policy. 197 with the organization to understand which framework they used to write their
197- *PasswordReusePrevention*: AWS allows a maximum of 24 previous passwords. If your 198 policy.
198organization's policy requires a higher number than AWS supports, document the 199- *PasswordReusePrevention*: AWS allows a maximum of 24 previous passwords. If
199platform limitation rather than raising it as a deficiency. 200 your organization's policy requires a higher number than AWS supports,
201 document the platform limitation rather than raising it as a deficiency.
200 202
201* How to Write Up the Finding 203* How to Write Up the Finding
202 204
203If a setting fails, here's how to frame it: 205If a setting fails, here's how to frame it:
204- *Deficiency:* The ~MinimumPasswordLength~ setting in the AWS IAM password policy is 206
205configured to ~6~, which is below the organization's requirement of ~8~ characters. 207- *Deficiency:* The ~MinimumPasswordLength~ setting in the AWS IAM password policy
208 is configured to ~6~, which is below the organization's requirement of ~8~
209 characters.
206- *Root Cause:* Due to {{ root cause }}, the policy was configured to enforce a 210- *Root Cause:* Due to {{ root cause }}, the policy was configured to enforce a
207 ~MinimumPasswordLength~ of ~6~. 211 ~MinimumPasswordLength~ of ~6~.
208- *Risk:* Shorter passwords are more susceptible to brute-force and credential 212- *Risk:* Shorter passwords are more susceptible to brute-force and credential
209stuffing attacks, increasing the likelihood of unauthorized access to the AWS 213 stuffing attacks, increasing the likelihood of unauthorized access to the AWS
210console. 214 console.
211- *Evidence:* Refer to ~policy_audit_<timestamp>.csv~ for documentation of testing. 215- *Evidence:* Refer to ~policy_audit_<timestamp>.csv~ for documentation of testing.
212 216
213The same structure applies to any other failing rule. For boolean settings, the 217The same structure applies to any other failing rule. For boolean settings, the