Managing external identities to enable secure access for partners, customers, and other non-employees
PATCH /beta/policies/b2bManagementPolicies/{id} is documented to support app-only authentication with Policy.ReadWrite.B2BManagementPolicy; if an unchanged, valid policy returned by GET still produces 404, capture a minimal REST reproduction and escalate it as a beta service/API failure rather than changing the policy ID or adding unrelated permissions.
Confirm the effective application permission
The update operation lists Policy.ReadWrite.B2BManagementPolicy as the least-privileged application permission. The Global Administrator role requirement applies to delegated access, not app-only access.^1^
Admin consent must result in that role appearing in the access token’s roles claim. Decode the token locally in Windows PowerShell 5.1:
$parts = $accessToken.Split('.')
$payload = $parts[1].Replace('-', '+').Replace('_', '/')
$payload += '=' * ((4 - $payload.Length % 4) % 4)
$claimsJson = [Text.Encoding]::UTF8.GetString(
[Convert]::FromBase64String($payload)
)
$claims = $claimsJson | ConvertFrom-Json
$claims.tid
$claims.appid
$claims.roles
The output should contain Policy.ReadWrite.B2BManagementPolicy. If it does not, grant/admin-consent the application permission and acquire a new token. Do not substitute another broad permission—the update contract lists no higher application permission.
Produce a minimal GET/PATCH reproduction
The API permits partial updates, but its property table identifies definition, description, and displayName as required policy properties. A successful update should return 200 OK and the updated object.^1^
Use the values returned by GET unchanged first. This separates an endpoint/authentication failure from an error in the domain-list transformation:
$id = "[GUID]"
$uri = "https://graph.microsoft.com/beta/policies/b2bManagementPolicies/$id"
$headers = @{
Authorization = "Bearer $accessToken"
"client-request-id" = [guid]::NewGuid().ToString()
"return-client-request-id" = "true"
}
$current = Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
$body = @{
description = $current.description
displayName = $current.displayName
definition = @($current.definition)
isOrganizationDefault = [bool]$current.isOrganizationDefault
} | ConvertTo-Json -Depth 20
Invoke-RestMethod -Method Patch -Uri $uri -Headers $headers `
-ContentType "application/json" -Body $body
The Graph PowerShell beta module exposes the equivalent Update-MgBetaPolicyB2BManagementPolicy command and documents the same application permission.^2^
Do not deserialize and rewrite the allowed-domain portion until its exact definition structure has been established from your tenant’s current policy. definition is a string collection containing JSON strings, and the available documentation does not specify the internal domain-list schema sufficiently to provide a safe generic add/remove implementation.^3^ Replacing it with a guessed structure could discard unrelated settings.
Capture the failed request for Microsoft support
For a 404, collect the Graph response headers as well as the body:
try {
Invoke-WebRequest -UseBasicParsing -Method Patch -Uri $uri `
-Headers $headers -ContentType "application/json" -Body $body
}
catch {
$response = $_.Exception.Response
[pscustomobject]@{
StatusCode = [int]$response.StatusCode
RequestId = $response.Headers["request-id"]
ClientRequestId = $response.Headers["client-request-id"]
Date = $response.Headers["Date"]
Error = $_.ErrorDetails.Message
} | Format-List
}
Attach these items to the support case:
- UTC date and time
- Tenant ID and application/client ID
- Request ID and client-request-id
- Exact URL and sanitized request body
- Successful GET response showing the same policy ID
- Token
rolesclaim - Confirmation that an unchanged GET-derived payload also fails
A public SDK issue reports the same inability to update this policy as an application. It was redirected to the API owners because it was not considered an SDK problem; it corroborates an API-layer issue but is not an official declaration that app-only PATCH is unsupported.^4^
The endpoint is beta, and Microsoft states that beta APIs are subject to change and are not supported for production applications.^1^ No separate, verified Microsoft Graph API for programmatically editing this allow list is documented in the supplied material.
Operational fallback
Until the API request is resolved, update the list in:
Microsoft Entra admin center → Entra ID → External Identities → External collaboration settings → Collaboration restrictions → Allow invitations only to the specified domains → Save
The documented portal procedure requires a Global Administrator. Back up the current entries before changing policy type because switching between allow and block lists discards the existing configuration.^5^
References
- Update b2bManagementPolicy - Microsoft Graph beta
- Imports the Microsoft.Graph.Beta.Identity.SignIns PowerShell module and updates the properties of a b2bManagementPolicy object using the Update-MgBetaPolicyB2BM...
- b2bManagementPolicy resource type
- Update B2BManagementPolicy · Issue #2273 · microsoftgraph/msgraph-sdk ...
- Allow or block B2B collaboration with organizations