{
  "id": "CB-M365-AUTH-025",
  "standard": "m365",
  "version": "main",
  "url": "https://baselines.cirsec.org/b/m365/CB-M365-AUTH-025",
  "json": "https://baselines.cirsec.org/b/m365/CB-M365-AUTH-025.json",
  "yaml": "https://baselines.cirsec.org/b/m365/CB-M365-AUTH-025.yml",
  "profiles_effective": [
    "baseline",
    "hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-M365-AUTH-025",
    "title": "Require users to sign in again at least every {{ user_signin_frequency_days }} days",
    "finding": {
      "title": "User sessions can stay valid for up to 90 days without a new sign-in",
      "description": "A stolen refresh token or session cookie keeps working for weeks, because nothing forces the user to authenticate again."
    },
    "status": "active",
    "profiles": [
      "baseline"
    ],
    "risk": {
      "severity": "medium"
    },
    "assessment": "manual",
    "tags": [
      "conditional-access",
      "session",
      "sign-in-frequency",
      "token-theft"
    ],
    "applicability": {
      "requires": [
        "Microsoft Entra ID P1"
      ]
    },
    "description": "A Conditional Access policy applies the **Sign-in frequency** session control to all users on all\nresources, with a periodic reauthentication of at most {{ user_signin_frequency_days }} days.\nWithout such a policy, Microsoft Entra ID uses a rolling 90-day window: a session is renewed as\nlong as it is used, and the user is not asked to authenticate again.\n\nAdministrators get a shorter frequency from CB-M365-AUTH-024; this control covers everyone else.\nIt excludes only the emergency access accounts.\n",
    "rationale": "Token theft (infostealer malware, adversary-in-the-middle phishing, a lost unlocked device) gives\nan attacker a session that survives a password change only until the next forced sign-in. A\nperiodic reauthentication caps how long a stolen refresh token or browser session stays useful,\nand makes the user prove again that they hold the password and the MFA method.\n",
    "impact": "Users are prompted to sign in and complete MFA once every {{ user_signin_frequency_days }} days\non each device and application. On Microsoft Entra joined or hybrid joined Windows devices with\nWindows Hello for Business the prompt is usually silent. Shorter values cause MFA fatigue and\nhelp-desk calls.\n",
    "notes": "Sign-in frequency applies to interactive sign-ins and to refresh tokens. It does not apply to\nservice principals or managed identities. If several policies set a frequency, the shortest one\nwins.\n",
    "parameters": [
      {
        "name": "user_signin_frequency_days",
        "type": "integer",
        "description": "Maximum number of days between two interactive sign-ins for regular users.",
        "unit": "days",
        "default": 7,
        "minimum": 1,
        "maximum": 90
      }
    ],
    "audit": {
      "manual": "1. Sign in to the Microsoft Entra admin center (https://entra.microsoft.com) as at least a\n   Security Reader.\n2. Browse to **Entra ID** > **Conditional Access** > **Policies**.\n3. Find a policy with **State** set to **On** where:\n   - **Users** > **Include** is **All users**, and **Exclude** contains only the emergency\n     access accounts or their group;\n   - **Target resources** includes **All resources**, without exclusions;\n   - **Session** > **Sign-in frequency** is enabled, **Periodic reauthentication**, with a value\n     of {{ user_signin_frequency_days }} days or less (or the equivalent in hours).\n4. Alternative in PowerShell (Microsoft Graph, scope `Policy.Read.All`):\n   `Get-MgIdentityConditionalAccessPolicy | Where-Object { $_.SessionControls.SignInFrequency.IsEnabled } | Select-Object DisplayName, State, @{n='Frequency';e={$_.SessionControls.SignInFrequency.Value, $_.SessionControls.SignInFrequency.Type}}`\n5. Fail if no enabled policy covers all users and all resources with a frequency of\n   {{ user_signin_frequency_days }} days or less.\n"
    },
    "remediation": {
      "manual": "1. Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator.\n2. Browse to **Entra ID** > **Conditional Access** > **Policies** and select **New policy**.\n3. Name it, for example `ALL - Sign-in frequency`.\n4. **Users** > **Include**: **All users**. **Exclude**: the emergency access accounts.\n5. **Target resources** > **Resources** > **Include**: **All resources**.\n6. **Session** > **Sign-in frequency** > **Periodic reauthentication**: enter\n   {{ user_signin_frequency_days }} and select **Days**.\n7. Set **Enable policy** to **Report-only**, save, and check the sign-in logs for a few days.\n8. Switch **Enable policy** to **On**.\n\nThe same policy can be created with `New-MgIdentityConditionalAccessPolicy` and a\n`sessionControls.signInFrequency` block (`value`, `type: days`, `isEnabled: true`).\n",
      "rollback": "Set the policy to **Report-only** or **Off**.\n"
    },
    "references": [
      {
        "title": "Configure adaptive session lifetime policies",
        "url": "https://learn.microsoft.com/entra/identity/conditional-access/howto-conditional-access-session-lifetime",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      },
      {
        "title": "Conditional Access adaptive session lifetime",
        "url": "https://learn.microsoft.com/entra/identity/conditional-access/concept-session-lifetime",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      }
    ],
    "mappings": [
      {
        "framework": "anssi-mfa",
        "framework_version": "2.0",
        "id": "R12",
        "relation": "related",
        "note": "ANSSI asks to limit the lifetime of authenticated sessions in general; ours sets a tenant-wide maximum for regular users."
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-12",
        "relation": "related"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "IA-11",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1539"
      },
      {
        "framework": "mitre-attack",
        "id": "T1550.001"
      }
    ],
    "related_controls": [
      {
        "id": "CB-M365-AUTH-026",
        "type": "related"
      },
      {
        "id": "CB-M365-AUTH-027",
        "type": "related"
      },
      {
        "id": "CB-M365-AUTH-028",
        "type": "related"
      },
      {
        "id": "CB-M365-AUTH-024",
        "type": "related"
      },
      {
        "id": "CB-M365-AUTH-003",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-24",
    "updated": "2026-10-24"
  }
}