hashicorp / terraform-provider-azuread

Terraform provider for Azure Active Directory
https://registry.terraform.io/providers/hashicorp/azuread/latest/docs
Mozilla Public License 2.0
420 stars 288 forks source link

azuread_authentication_strength_policy deployment fails with CLI authentication user #1281

Open flymg opened 8 months ago

flymg commented 8 months ago

Community Note

Terraform (and AzureAD Provider) Version

Terraform v1.6.6 on darwin_arm64

Affected Resource(s)

Terraform Configuration Files

provider "azuread" {
  tenant_id = "***"
}

resource "azuread_authentication_strength_policy" "test" {
  display_name = "test"
  description  = "test"
  allowed_combinations = [
    "password"
  ]
}

Debug Output

https://gist.github.com/flymg/90746450c085a1e6e8fa89e8e6c978a0

Panic Output

Expected Behavior

apply or import working

Actual Behavior

azuread_authentication_strength_policy.test: Creating...
â•·
│ Error: Could not create authentication strength policy
│ 
│   with azuread_authentication_strength_policy.test,
│   on test.tf line 5, in resource "azuread_authentication_strength_policy" "test":
│    5: resource "azuread_authentication_strength_policy" "test" {
│ 
│ AuthenticationStrengthPoliciesClient.BaseClient.Post():
│ unexpected status 403 with OData error: accessDenied:
│ Request Authorization failed: Request Authorization failed

Steps to Reproduce

terraform apply

Important Factoids

Authentication is done with a user with Global Administrator rights via az login and interactive dialog.

References

flymg commented 8 months ago

looking into the detailed logs, it seems that with the user auth method via CLI only the following is in the token:

"scp":"AuditLog.Read.All Directory.AccessAsUser.All email Group.ReadWrite.All openid profile User.ReadWrite.All"

which would miss the required permissions from the instructions https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/authentication_strength_policy

When authenticated with a service principal, this resource requires the following application roles: Policy.ReadWrite.ConditionalAccess and Policy.Read.All

SiteNote:
The login and the user is fine, MSGraph access works with powershell implementation.

manicminer commented 3 months ago

@flymg Thanks for reporting this and apologies for the delay. When you authenticate as a user, that user must have a directory role that confers the necessary permissions, as application roles don't apply to users. Of the built-in directory roles, those with the necessary permissions are either "Conditional Access Administrator" or "Global Administrator" - you would need to assign one of these to your user account in order to use this resource.

flymg commented 3 months ago

Hi @manicminer, i can confirm, that the special account being used has the

image

I can also confirm, that with a minimum example of MSGraph this works fine with this account (keeping terraform out of the equation)

i'm still assuming, that the auth does not request the necessary scope for the operation

"scp":"AuditLog.Read.All Directory.AccessAsUser.All email Group.ReadWrite.All openid profile User.ReadWrite.All"

As you can see, Policy.ReadWrite.ConditionalAccess is not there although the user has the entitlement.

How can one force to request that within the auth?

manicminer commented 3 months ago

@flymg I've done some testing on my end and I'm actually encountering the same issue. I have tried assigning the following directory roles to no avail:

I'm getting a 403 when creating an auth strength policy. I've tried with both a B2B account and a local tenant account with the same result. This leads to me suspect this is an API issue and I'd recommend raising an Azure support ticket.

I don't believe the issue lies with token scopes - for one the client doesn't usually request specific scopes, and second I believe the Directory.AccessAsUser.All scope enables the client to act as the user, inheriting whatever permissions they have from directory roles.

flymg commented 3 months ago

Hi @manicminer, thanks for the update. As said, i have done this with a minimal example setting it with the azure powershell cli.

Within this, i see that in the request Policy.ReadWrite.ConditionalAccess is included and it runs through successfully, an Azure Authentication Strength gets deployed. The auth mechanism is of course the one from Powershell CLI.

The Azure API is working fine from this point, so a ticket does not make sense there.

I can only assume, that the Policy.ReadWrite.ConditionalAccess is the missing piece here, because that is what is missing in the terraform request. I cannot tell weather Directory.AccessAsUser.All would include this, but as you are getting the exact 403 error as we do, it might not do it.

manicminer commented 3 months ago

@flymg Thanks for the clarification. In that case, this feels like a limitation of Azure CLI.

When we lean on Azure CLI for authentication, we are also dependent on it for authorization. In our tenant(s), running the following yields a consent error:

az account get-access-token --resource-type ms-graph --tenant 00000000-0000-0000-0000-000000000000 --scope 'Policy.ReadWrite.ConditionalAccess'
{
  "error": "invalid_request",
  "error_description": "AADSTS65002: Consent between first party application '04b07795-8ddb-461a-bbee-02f9e1bf7b46' and first party resource '00000003-0000-0000-c000-000000000000' must be configured via preauthorization - applications owned and operated by Microsoft must get approval from the API owner before requesting tokens for that API. Trace ID: cf8d2056-7825-4d94-8ded-d7a178d9e700 Correlation ID: 6642d1d2-aaa5-49d0-a022-1c71dbbe0f56 Timestamp: 2024-05-16 13:58:51Z",
  "error_codes": [
    65002
  ],
  "timestamp": "2024-05-16 13:58:51Z",
  "trace_id": "cf8d2056-0000-0000-0000-000000000000",
  "correlation_id": "6642d1d2-0000-0000-0000-000000000000",
  "error_uri": "https://login.microsoftonline.com/error?code=65002"
}

There is no Azure CLI service principal in our tenants for which we can grant consent, I think this is due to az-cli being a legacy first-party app. I also don't believe that Azure CLI supports Conditional Access natively, so is unlikely to have this scope in its manifest. Which would seem to leave us stuck here - Azure CLI can seemingly not acquire an access token with this scope so neither can we.