Back to Checks
okta

Every active Okta Password Policy enforces a maximum password age of 60 days or less

authenticator_password_maximum_age_60d
Service: authenticatorSeverity: low
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:NotDefined

Every active Okta Password Policy must require users to change their password at least every 60 days. The check rejects both unlimited expiration (0, which Okta treats as never expires) and any value greater than 60.

Okta evaluates Password Policies by group assignment; a permissive custom policy with a longer window can govern users. The check emits one finding per active policy.

Risk

Long-lived passwords give a compromised credential indefinite usefulness.

  • Stolen passwords stay valid until the user happens to change them
  • Breach detection lag means a leaked password can be in use for months unnoticed
  • No expiration is the same risk as an infinite expiration window

Run this check with Prowler

Run in Prowler Cloud
Run
prowler okta --checks authenticator_password_maximum_age_60d

Recommendation

Configure every active Okta Password Policy so:

  • Enforce password expiration is 60 days or less
  • Never set the value to 0, which disables expiration
  • Group assignments do not route users to legacy policies with longer windows or disabled expiration

Review each active Password Policy individually — the check evaluates them one at a time.

Remediation

Terraform

resource "okta_policy_password" "<example_resource_name>" {
  name                = "<example_resource_name>"
  status              = "ACTIVE"
  password_max_age_days = 60  # Critical: STIG-aligned maximum age; do not use 0 (disables expiration)
}

Other

1Sign in to the **Okta Admin Console** as a *Super Admin*.
2Navigate to **Security** > **Authentication** > **Password**.
3For every active policy, click **Edit** and set *Enforce password expiration* to `60` days or less. Do **not** leave it disabled or set to `0` — that disables expiration entirely.
4Save the policy.
5Repeat for every active Password Policy returned by the check.

Check Code

from prowler.lib.check.models import Check, CheckReportOkta
from prowler.providers.okta.services.authenticator.authenticator_client import (
    authenticator_client,
)
from prowler.providers.okta.services.authenticator.lib.password_policy_helpers import (
    active_password_policies,
    missing_password_policies_scope_finding,
    no_active_password_policies_finding,
    password_policy_label,
)


class authenticator_password_maximum_age_60d(Check):
    """STIG V-273201 / OKTA-APP-000745.

    Every active Okta Password Policy must enforce a 60-day maximum password age.
    The check emits one finding per active policy so a weaker
    custom policy cannot hide behind a compliant default.
    """

    def execute(self) -> list[CheckReportOkta]:
        """Evaluate all active Okta Password Policies."""
        findings = []
        org_domain = authenticator_client.provider.identity.org_domain
        requirement = "maximum password age of 60 days or less"
        missing_scope = authenticator_client.missing_scope.get("password_policies")

        if missing_scope:
            return [
                missing_password_policies_scope_finding(
                    self.metadata(), org_domain, missing_scope, requirement
                )
            ]

        policies = active_password_policies(authenticator_client.password_policies)
        if not policies:
            return [
                no_active_password_policies_finding(
                    self.metadata(), org_domain, requirement
                )
            ]

        for policy in policies:
            report = CheckReportOkta(
                metadata=self.metadata(), resource=policy, org_domain=org_domain
            )
            if policy.max_age_days is not None and 0 < policy.max_age_days <= 60:
                report.status = "PASS"
                report.status_extended = (
                    f"{password_policy_label(policy)} enforces {requirement} "
                    f"(maximum age days: {policy.max_age_days})."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"{password_policy_label(policy)} does not enforce {requirement} "
                    f"(maximum age days: {policy.max_age_days})."
                )
            findings.append(report)
        return findings