Connect to your tenant
SPNRoleMgr runs entirely in your browser. It signs you in with Microsoft (PKCE) and queries Microsoft Graph as you. No backend, no telemetry, no data leaves your browser.
Required delegated permissions:
Application.Read.All- list service principals and the API surfaces they consumeDirectory.Read.All- resolve owners and other directory metadataUser.Read- sign-in identityAppRoleAssignment.ReadWrite.All(only when you actually save changes)DelegatedPermissionGrant.ReadWrite.All(only when you actually save changes)
To grant tenant-wide application permissions or delegated grants for all users, your account also needs a privileged role: Privileged Role Administrator, Cloud Application Administrator, Application Administrator or Global Administrator. Without one of these, Graph will return 403 on save.
Debug log
About SPNRoleMgr
SPNRoleMgr is part of the LCToolkit by Lieben Consultancy. It lets you inspect and modify the API permissions of any service principal or managed identity in your tenant. The user interface mimics the "Add a permission" experience on Entra app registrations, but works for SPNs that have no app registration in your tenant (managed identities, federated apps, multi-tenant apps).
What it can do
- Browse every service principal in the tenant with quick filters for type and Microsoft first-party.
- For a chosen SPN, list both application permissions (
appRoleAssignments) and delegated grants (oauth2PermissionGrants) it currently has. - Revoke any single permission (per-permission delete, not per-API).
- Pick any API exposed in the tenant (Microsoft Graph, SharePoint, Exchange, Azure-Storage, third-party APIs you've consented to, etc.) and grant either application or delegated permissions on it.
How it works
- Listing SPNs:
GET /servicePrincipals?$top=999withConsistencyLevel: eventualfor max throughput. - Listing permissions:
GET /servicePrincipals/{id}/appRoleAssignments+GET /servicePrincipals/{id}/oauth2PermissionGrantsin parallel. - Resolving names: when an assignment points at a resource SPN we don't have cached, we look up
GET /servicePrincipals/{resourceId}to translate the role/scope GUID into a human-readable name. - Granting: for application permissions we POST to
/servicePrincipals/{spId}/appRoleAssignmentswith{principalId, resourceId, appRoleId}. For delegated, we look for an existingoauth2PermissionGrantsentry with the same client+resource+consentType and PATCH itsscopestring; if none exists we POST a new one withconsentType=AllPrincipals. - Revoking: DELETE on the assignment or grant id; for delegated, if removing the last scope from a grant we delete the grant entirely.
What it does NOT do
- It does not change the application's own published API surface (i.e. it doesn't edit the resource SPN's
appRolesoroauth2PermissionScopes). To do that, edit the underlying app registration in Entra. - It does not assign Entra directory roles (Global Admin, Reader, etc.). Use Entra for that.
- It does not configure Conditional Access, app authentication policies, or password/certificate credentials.
Required permissions
Read-only browsing only needs Application.Read.All + Directory.Read.All. The first time you save a change SPNRoleMgr asks for AppRoleAssignment.ReadWrite.All and DelegatedPermissionGrant.ReadWrite.All. Granting tenant-wide also requires you to hold a privileged Entra role (Privileged Role Admin, Cloud App Admin, Application Admin or Global Admin); without one, Graph returns 403 on the save.