Removing the Relay
When you stop using Calibrant — or you just want the relay gone — this page removes every trace of it from your Azure subscription and your Microsoft 365 tenant. Most of the time is spent waiting for Azure to delete the VM; timing varies by region and service availability.
The short version is delete the resource group. That removes the VM and the Managed Identity, and the Managed Identity is what held all the permissions. The rest of this page is the parts that are not obvious.
Three things worth knowing first
Access does not stop the instant you delete. Tokens issued before deletion stay valid until they expire, and Azure caches Managed Identity tokens for roughly 24 hours. Some Microsoft endpoints re-check the directory and start failing immediately; others honour the token until it expires. If you need access to stop at a specific moment — during an incident, say — delete the resource group and then treat the following 24 hours as a wind-down window rather than a hard cutoff.
The identity stays visible for 30 days. Microsoft soft-deletes Managed Identities, and "you can view the soft deleted managed identity service principal, but you cannot restore or permanently delete it." Seeing it in Entra ID after you delete it is expected and does not mean the deletion failed. It holds no permissions in that state, and you cannot purge it early.
Step 1 — See what the relay identity currently holds
Before changing anything, get a baseline. This script only reads — it requests read-only Graph scopes and issues no writes, so it is safe to run against production without thinking about it. Global Reader is enough; you do not need Global Administrator.
↓ Download check-relay-permissions.ps1
# In a pwsh 7 terminal on your own machine (not the VM):
./check-relay-permissions.ps1It prints the tenant it connected to, then every application permission, directory role, and group membership the identity holds. On a relay granted by the current script expect 19 application permissions, 1 directory role (Global Reader), and — if you enabled the Fabric checks — 1 group. Relays granted before August 2026 will also show legacy Graph roles and up to five legacy directory roles; the script flags those as removable. It exits 0 when the identity holds nothing and 1 when anything remains, so you can use it as a gate in your own offboarding checklist.
-TenantId so there is no ambiguity at all.If you deployed with different names, see Customising the check script below.
Step 2 — Delete the Azure resources
This deletes the VM, the Managed Identity, the virtual network, the NSG, and the Log Analytics workspace in one operation, and it is the step that actually removes the relay's access to your tenant.
az group delete --name calibrant-relay-rg --yes
# If you deployed to a different resource group, list them first:
az group list --query "[?contains(name,'calibrant')].name" -o tsvDeletion takes a few minutes. If you would rather keep the VM — to redeploy later without paying to rebuild it — delete just the identity instead. The relay stops working immediately, and the VM sits there with no access to anything:
az identity delete --name calibrant-relay-identity --resource-group calibrant-relay-rgStep 3 — Clean up what Azure cannot reach
Three things live outside Azure and outside Entra ID, so deleting the resource group does not touch them. Two are tenant settings you changed for Calibrant and would otherwise stay changed.
Fabric admin portal settings
During setup you enabled two service principal settings in the Fabric admin portal, each scoped to a security group. Both stay enabled after the relay is gone. Turn them off if nothing else uses them:
- Developer settings > Service principals can call Fabric public APIs
- Admin API settings > Service principals can access read-only admin APIs
Then delete the security group you created for this (commonly named FabricApiAccess) if it exists only for Calibrant. It will be empty once the identity is deleted, but an empty group left in an allowlist is a trap for whoever finds it later.
Power Platform management application
The relay was registered with Power Platform so it could read DLP policies and environments. That registration lives in Power Platform, keyed by the identity's application (client) ID — not in Entra ID, so it does not appear in any directory role listing and deleting the resource group does not remove it.
Run the check script to see whether it is still listed in your tenant; if it is, remove it:
$t = az account get-access-token --resource https://api.bap.microsoft.com/ --query accessToken -o tsv
Invoke-RestMethod -Method DELETE -Headers @{ Authorization = "Bearer $t" } `
-Uri 'https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/adminApplications/<client-id>?api-version=2020-10-01'You need the client ID for this, so capture it before you delete the resource group — it is much harder to find afterwards:
az identity show --name calibrant-relay-identity --resource-group calibrant-relay-rg --query clientId -o tsvDirectory roles
Global Reader — and on older relays the legacy Exchange, Teams, SharePoint, Power Platform and Fabric Administrator roles — are directory role memberships held by the identity, so they go when the identity does. Nothing to do here, but Step 5 verifies it rather than assuming it.
Step 4 — Remove the relay from Calibrant
Go to Connections, find the relay under Calibrant Relay, and delete it. This invalidates its API key, so even a VM you kept can no longer reach Calibrant.
If you are leaving entirely, go to Settings and request account deletion. Calibrant begins the checked deletion immediately: it cancels the linked subscription, removes the live workspace data and relay credential hashes, and removes the workspace members' Calibrant sign-in accounts. Calibrant does not retain a customer Microsoft OAuth token and does not offer a 30-day undo window. Provider-managed backup copies age out under the backup-retention window. See the privacy policy for what is kept and for how long.
Step 5 — Verify
Run the check script again. Do not skip this because the deletion appeared to succeed — confirming it is the entire point, and it takes fifteen seconds.
./check-relay-permissions.ps1 -ApplicationId <client-id>Expect:
Not found in this tenant— or a[SOFT-DELETED]note, which is fineResource group not foundPower Platform: Not registeredCLEAR - this identity holds no access, and exit code0
Anything reported as [HELD] is still live. Re-run the relevant step above.
Customising the check script
The defaults match what the Bicep template creates. If you renamed anything, deployed more than one relay, or administer several tenants, pass the parameters below. Every one of them is optional.
| Parameter | When you need it | How to find the value |
|---|---|---|
-DisplayName | You gave the Managed Identity a name other than calibrant-relay-identity | az identity list --query "[].name" -o tsv |
-ServicePrincipalId | Several identities share a display name, or you want zero ambiguity. Overrides -DisplayName | az identity show -n <name> -g <rg> --query principalId -o tsv |
-ApplicationId | Checking the Power Platform registration, or the identity is already deleted and this is the only handle left | az identity show -n <name> -g <rg> --query clientId -o tsv |
-TenantId | Your admin account can reach more than one tenant. Strongly recommended for partners and MSPs | az account show --query tenantId -o tsv |
-SubscriptionId | The relay is not in the subscription your Azure CLI currently points at | az account list --query "[].{name:name, id:id}" -o table |
-ResourceGroupName | You deployed somewhere other than calibrant-relay-rg | az group list --query "[].name" -o tsv |
-SkipAzureCheck | You have Graph access but no Azure CLI, or no rights to the subscription | — |
-SkipPowerPlatformCheck | You never used the Power Platform checks | — |
-Json | Checking many tenants and collecting results | — |
A fully specified run looks like this:
./check-relay-permissions.ps1 `
-TenantId contoso.onmicrosoft.com `
-DisplayName 'contoso-relay-mi' `
-ResourceGroupName 'rg-calibrant-prod' `
-SubscriptionId 00000000-0000-0000-0000-000000000000 `
-ApplicationId 11111111-1111-1111-1111-111111111111And across many tenants, collecting the results:
$tenants = @('contoso.onmicrosoft.com','fabrikam.onmicrosoft.com')
$tenants | ForEach-Object {
./check-relay-permissions.ps1 -TenantId $_ -Json | ConvertFrom-Json
} | Select-Object tenantDomain, identityFound, holdsNothing | Format-TableVerifying the script before you run it
It is a PowerShell script downloaded over the internet, so treat it like one. It requests only Directory.Read.All and Application.Read.All and contains no write operations — you can confirm both by reading it, and by comparing your download against the copy in our public repository:
# Windows
Get-FileHash .\check-relay-permissions.ps1 -Algorithm SHA256
# Mac / Linux
shasum -a 256 check-relay-permissions.ps1The digest and the file come from the same origin, so this catches a corrupted or modified download rather than serving as independent attestation. The script only reads — you can confirm that by searching it for Remove-, Set-, or New- and finding none.
What Calibrant keeps
Removing the relay stops all collection. It does not delete scan history already stored in Calibrant — that follows the retention policy, and you can delete individual scans from the results pages or request full account deletion in Settings. See the privacy policy for retention windows by plan.