msgraph-metadata icon indicating copy to clipboard operation
msgraph-metadata copied to clipboard

Conditional Access Policies: `sessionControls.signInFrequency.frequencyInterval: "everyTime"` is not supported in v1.0 API

Open manicminer opened this issue 1 year ago • 5 comments

According to documentation, it should be possible to specify frequencyInterval: "everyTime" in the signInFrequencySessionControl model in the v1.0 API, however it seems this always returns a 400 response instructing to use the Beta endpoint.

Here is the request I am sending to create a conditional access policy:

POST /v1.0/identity/conditionalAccess/policies HTTP/1.1
Host: graph.microsoft.com
User-Agent: HashiCorp Terraform/1.7.5 (+https://www.terraform.io) Terraform Plugin SDK/2.10.1 terraform-provider-azuread/dev Hamilton (Go-http-client/1.1) pid-222c6c49-1b0a-5959-a213-6608f9eb8820
Content-Length: 895
Accept: application/json; charset=utf-8; IEEE754Compatible=false
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub...
Content-Type: application/json; charset=utf-8
Odata-Maxversion: 4.0
Odata-Version: 4.0
Accept-Encoding: gzip

{
  "conditions": {
    "applications": {
      "includeApplications": [
        "All"
      ],
      "excludeApplications": [],
      "includeUserActions": []
    },
    "clientAppTypes": [
      "browser"
    ],
    "devices": null,
    "locations": {
      "includeLocations": [
        "All"
      ],
      "excludeLocations": []
    },
    "platforms": {
      "includePlatforms": [
        "all"
      ],
      "excludePlatforms": []
    },
    "servicePrincipalRiskLevels": [],
    "signInRiskLevels": [],
    "userRiskLevels": [],
    "users": {
      "includeUsers": [
        "All"
      ],
      "excludeUsers": [
        "GuestsOrExternalUsers"
      ],
      "includeGroups": [],
      "excludeGroups": [],
      "includeRoles": [],
      "excludeRoles": [],
      "includeGuestsOrExternalUsers": null,
      "excludeGuestsOrExternalUsers": null
    }
  },
  "displayName": "acctest-CONPOLICY-240625230036522960",
  "grantControls": null,
  "sessionControls": {
    "applicationEnforcedRestrictions": {
      "isEnabled": false
    },
    "cloudAppSecurity": null,
    "disableResilienceDefaults": false,
    "persistentBrowser": null,
    "signInFrequency": {
      "frequencyInterval": "everyTime",
      "isEnabled": true
    }
  },
  "state": "disabled"
}

And the response:

HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: application/json
Content-Encoding: gzip
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: 320c19a9-5002-4a0e-9369-34ff925d0f94
client-request-id: 320c19a9-5002-4a0e-9369-34ff925d0f94
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"UK South","Slice":"E","Ring":"5","ScaleUnit":"000","RoleInstance":"LN2PEPF000114CC"}}
Date: Tue, 25 Jun 2024 22:01:02 GMT

{
  "error": {
    "code": "BadRequest",
    "message": "1038: The policy you are trying to create or update contains preview features. Use the Beta endpoint to create or update this policy.",
    "innerError": {
      "date": "2024-06-25T22:01:03",
      "request-id": "320c19a9-5002-4a0e-9369-34ff925d0f94",
      "client-request-id": "320c19a9-5002-4a0e-9369-34ff925d0f94"
    }
  }
}

If I send this same request to the beta endpoint, it is accepted:

POST /beta/identity/conditionalAccess/policies HTTP/1.1
Host: graph.microsoft.com
User-Agent: HashiCorp Terraform/1.7.5 (+https://www.terraform.io) Terraform Plugin SDK/2.10.1 terraform-provider-azuread/dev Hamilton (Go-http-client/1.1) pid-222c6c49-1b0a-5959-a213-6608f9eb8820
Accept: application/json; charset=utf-8; IEEE754Compatible=false
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub...
Content-Type: application/json; charset=utf-8
Odata-Maxversion: 4.0
Odata-Version: 4.0
Accept-Encoding: gzip
Connection: close
Content-Length: 895

{
  "conditions": {
    "applications": {
      "includeApplications": [
        "All"
      ],
      "excludeApplications": [],
      "includeUserActions": []
    },
    "clientAppTypes": [
      "browser"
    ],
    "devices": null,
    "locations": {
      "includeLocations": [
        "All"
      ],
      "excludeLocations": []
    },
    "platforms": {
      "includePlatforms": [
        "all"
      ],
      "excludePlatforms": []
    },
    "servicePrincipalRiskLevels": [],
    "signInRiskLevels": [],
    "userRiskLevels": [],
    "users": {
      "includeUsers": [
        "All"
      ],
      "excludeUsers": [
        "GuestsOrExternalUsers"
      ],
      "includeGroups": [],
      "excludeGroups": [],
      "includeRoles": [],
      "excludeRoles": [],
      "includeGuestsOrExternalUsers": null,
      "excludeGuestsOrExternalUsers": null
    }
  },
  "displayName": "acctest-CONPOLICY-240625230036522960",
  "grantControls": null,
  "sessionControls": {
    "applicationEnforcedRestrictions": {
      "isEnabled": false
    },
    "cloudAppSecurity": null,
    "disableResilienceDefaults": false,
    "persistentBrowser": null,
    "signInFrequency": {
      "frequencyInterval": "everyTime",
      "isEnabled": true
    }
  },
  "state": "disabled"
}

This returns the expected 201 response:

HTTP/1.1 201 Created
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
Content-Encoding: gzip
Location: https://na.prod.graph.ipc.msidentity.com/conditionalAccess/policies('22e89125-b41c-4d8a-9811-598cd3c70366')
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: edcc0a03-c654-4bb5-8ae0-5568f6c6ed72
client-request-id: edcc0a03-c654-4bb5-8ae0-5568f6c6ed72
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"UK South","Slice":"E","Ring":"5","ScaleUnit":"000","RoleInstance":"LN2PEPF000114C1"}}
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:networkAccess&from=2022-02-01&to=2022-03-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:secureAppSessionMode&from=2023-07-01&to=2023-08-01>;rel="deprecation";type="text/html"
Link: <https://developer.microsoft-tst.com/en-us/graph/changes?$filterby=beta,PrivatePreview:secureAppSessionMode&from=2023-07-01&to=2023-08-01>;rel="deprecation";type="text/html"
Deprecation: Thu, 17 Feb 2022 23:59:59 GMT
Sunset: Sat, 17 Feb 2024 23:59:59 GMT
OData-Version: 4.0
Date: Tue, 25 Jun 2024 22:01:19 GMT
Connection: close

{
  "@odata.context": "https://graph.microsoft.com/beta/$metadata#identity/conditionalAccess/policies/$entity",
  "id": "22e89125-b41c-4d8a-9811-598cd3c70366",
  "templateId": null,
  "displayName": "acctest-CONPOLICY-240625230036522960",
  "createdDateTime": "2024-06-25T22:01:18.2770637Z",
  "modifiedDateTime": null,
  "state": "disabled",
  "grantControls": null,
  "partialEnablementStrategy": null,
  "conditions": {
    "userRiskLevels": [],
    "signInRiskLevels": [],
    "clientAppTypes": [
      "browser"
    ],
    "times": null,
    "deviceStates": null,
    "devices": null,
    "clientApplications": null,
    "applications": {
      "includeApplications": [
        "All"
      ],
      "excludeApplications": [],
      "includeUserActions": [],
      "includeAuthenticationContextClassReferences": [],
      "applicationFilter": null
    },
    "users": {
      "includeUsers": [
        "All"
      ],
      "excludeUsers": [
        "GuestsOrExternalUsers"
      ],
      "includeGroups": [],
      "excludeGroups": [],
      "includeRoles": [],
      "excludeRoles": [],
      "includeGuestsOrExternalUsers": null,
      "excludeGuestsOrExternalUsers": null
    },
    "platforms": {
      "includePlatforms": [
        "all"
      ],
      "excludePlatforms": []
    },
    "locations": {
      "includeLocations": [
        "All"
      ],
      "excludeLocations": []
    }
  },
  "sessionControls": {
    "disableResilienceDefaults": null,
    "applicationEnforcedRestrictions": null,
    "cloudAppSecurity": null,
    "persistentBrowser": null,
    "continuousAccessEvaluation": null,
    "secureSignInSession": null,
    "signInFrequency": {
      "value": null,
      "type": null,
      "authenticationType": "primaryAndSecondaryAuthentication",
      "frequencyInterval": "everyTime",
      "isEnabled": true
    }
  }
}

I picked this up after noticing that the Portal is using the Beta endpoint here, presumably due to this issue?

The problem with using the Beta endpoint, is that it locks a policy into using "beta features" and you can no longer use the v1.0 API to work with it.

Downstream issue: https://github.com/hashicorp/terraform-provider-azuread/pull/1417

manicminer avatar Jun 25 '24 22:06 manicminer

Spoke to one of the product group I'm talking to for something else that is CA and Graph related and they've nudged the engineering team re this issue (I was hitting this issue myself this week). Hopefully that gets it some momentum.

goldjg avatar Aug 31 '24 05:08 goldjg

Hi @manicminer & @goldjg ,our eng team verified that Sign-in Frequency every time is a partially GA feature - we currently support 3 scenarios in GA, listed in Conditional Access adaptive session lifetime policies - Microsoft Entra ID | Microsoft Learn

This is why the session control is still in the Beta API. There's active ongoing work to bring this to full GA, at which time the control will be available in Graph v1.0.

lisaychuang avatar Sep 04 '24 18:09 lisaychuang

Hi Lisa, The issue I had is that if I want to enforce a passwordChange and MFA grant control (for users whose UserRisk is High) then I’m being forced to select everyTime signinFrequency (in Terraform and also via the portal).

And that is where Terraform is being told by the v1.0 API endpoint to use the beta endpoint instead.

So if passwordChange+everyTime is a GA feature per the referenced documentation then it should work via the v1.0 endpoint.

I also wanted to set persistentBrowser to “never” but it won’t allow that in combination with the other settings. I also wanted to set signinFrequency to 1 hour alongside passwordChange but the response from TF/API is that you have to use everyTime if you use passwordChange.

So there seems to be some either coding errors or documentation errors re what is an allowed combination of settings. On 4 Sep 2024 at 19:33 +0100, Lisa Huang-North @.***>, wrote:

Hi @manicminer & @goldjg ,our eng team verified that Sign-in Frequency every time is a partially GA feature - we currently support 3 scenarios in GA, listed in Conditional Access adaptive session lifetime policies - Microsoft Entra ID | Microsoft Learn This is why the session control is still in the Beta API. There's active ongoing work to bring this to full GA, at which time the control will be available in Graph v1.0. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

goldjg avatar Sep 04 '24 19:09 goldjg

See https://github.com/hashicorp/terraform-provider-azuread/issues/1225#issuecomment-2577805105

Still can't get this to work... (azuread provider v 3.0.2)

Consider the following TF:

resource "azuread_conditional_access_policy" "Require_password_change_For_licensed_users_When_high_user_risk_is_detected" {
  display_name = "Require_password_change_For_licensed_users_When_high_user_risk_is_detected"
  state        = "enabledForReportingButNotEnforced"

  conditions {
    client_app_types = [
      "all",
    ]
    sign_in_risk_levels = []
    user_risk_levels = [
      "high",
    ]
    service_principal_risk_levels = []

    applications {
      excluded_applications = []
      included_applications = [
        "All",
      ]

    }

    users {
      excluded_groups = []
      excluded_roles  = []
      excluded_users  = []
      included_groups = []
      included_roles  = []
      included_users = [
        "None"
      ]
    }
  }

  grant_controls {
    built_in_controls = [
      "mfa",
      "passwordChange"
    ]
    custom_authentication_factors = []
    operator                      = "AND"
    terms_of_use                  = []
  }
  session_controls {
    cloud_app_security_policy                 = null
    disable_resilience_defaults               = null
    persistent_browser_mode                   = null
    sign_in_frequency_authentication_type = "primaryAndSecondaryAuthentication"
    sign_in_frequency_interval            = "everyTime"
    sign_in_frequency_period              = "hours"
    sign_in_frequency                     = 1
  }
}

This still returns:

│ unexpected status 400 (400 Bad Request) with error: BadRequest: 1115: The
│ specified session controls, 'applicationEnforcedRestrictions,
│ disableResilienceDefaults', are not supported with the password change
│ control; only signInFrequency every time is supported. For examples, please
│ see the API documentation at
│ https://docs.microsoft.com/en-us/graph/api/conditionalaccessroot-post-policies?view=graph-rest-1.0.

AdmiralGold avatar Jan 08 '25 14:01 AdmiralGold

Is there any update on this? The Portal still seems to use the Beta endpoint. What is the recommended way for automating these parts over an API? Does Microsoft recommend to use the Beta API for this and can Microsoft give some guarantees regarding format and behaviour stability on the Beta API?

FrediWeber avatar May 27 '25 08:05 FrediWeber