Black Shard

Insights18 July 2026

What to check in an Entra ID app registration security review

App registrations and service principals authenticate as themselves, with no user and no multi-factor claim for a conditional access policy to evaluate. A review of that plane asks which app-only permissions are granted, which credentials can use them, who can quietly add another one, and what the tenant settings do about the next grant.

A narrow steel service door beside a building's main glass entrance, lit cold cyan on dark slate

What does an Entra ID app registration security review cover?

Three objects carry the whole subject and the portal names them inconsistently. An app registration creates an application object, which is the definition of an application: the permissions it asks for, the credential types it may use, the accounts it will accept. A service principal is the instance of that application inside a tenant, and it is the object holding granted permissions, role assignments and live credentials. App registrations lists the application objects your own tenant owns; enterprise applications lists service principals. A third-party product appears only in the second list, because its application object lives in the vendor's tenant and only the service principal is yours.

Permissions come in two kinds and the difference decides how serious a finding is. Delegated permissions let an application act as a signed-in user, so the effective access is the overlap between the scope granted and what that user could already reach. Application permissions are granted as app roles, require administrator consent, and let the application act as itself with no user present. Microsoft states the consequence plainly for Exchange Online: by default, an application granted application permissions to mail can access every mailbox in the organisation, and the same holds for calendars, contacts and mailbox settings. A review reads the tenant from the service principal side and asks four things of every application that matters, which are what it holds, which credentials can authenticate as it, who else can add one, and where it has been signing in from.

Why a conditional access policy does not stop an app-only token

In the client credentials flow the service principal presents its own secret or certificate to the token endpoint and receives an access token for itself. There is no user, no device, no sign-in risk signal and no multi-factor claim, so a conditional access policy scoped to users has nothing to evaluate. Microsoft draws the boundary in the conditional access documentation: policies can be applied to single-tenant service principals registered in your tenant, and Microsoft and third-party SaaS applications, including multitenant apps, are not covered. A tenant can require phishing-resistant authentication on a compliant device for every person in it and still be read end to end by an application permission granted three years ago.

Conditional access for workload identities closes part of the gap and its limits decide how much. It requires Workload Identities Premium licensing, and it reaches single-tenant service principals registered in your own tenant, which leaves out the vendor application someone consented to last quarter along with managed identities. The conditions available are network location and risk detected by ID Protection, optionally combined with authentication context, and the only grant control is block. One detail defeats the obvious deployment: a policy assigned to a group containing a service principal is not enforced against it, so the assignment has to name the workload identity directly.

Which application permissions matter most once they are granted

Microsoft Graph publishes hundreds of permissions and almost none of them decide an engagement. Read the application permissions first, because they act with no user in front of them. Application.ReadWrite.All lets an application add a credential to another application and authenticate as it, and Microsoft's permissions reference carries the warning directly: permissions that allow managing credentials allow an application to act as other entities and use the privileges they were granted. AppRoleAssignment.ReadWrite.All is documented in similar terms, as a permission letting an app manage permission grants and elevate privileges for any app, user or group in the organisation. RoleManagement.ReadWrite.Directory is the compressed version of both, because directory role management is what assigns Global Administrator.

The mail rows deserve their own note, because the scoping tool lives in a different console from the grant and the two do not subtract. Granting mail permissions happens in Entra, while restricting an application to a defined set of mailboxes happens in Exchange Online through role-based access control for applications, which has replaced application access policies. Microsoft's documentation is explicit that permissions assigned in Exchange RBAC form a union with the grants made in Entra, so an application carrying an unscoped Mail.Read in Entra and a scoped Mail.Read in Exchange still reads every mailbox. Scoping means nothing until the Entra grant is removed, and a review reading the Exchange side alone will report a scoped application that is not scoped at all.

Application permissionWhat it reaches with no user presentTighter option
Mail.ReadWrite and Mail.SendEvery mailbox in the organisation, including sending as any userAssign the equivalent role in Exchange RBAC for applications against a management scope, then remove the Entra grant
Files.ReadWrite.All and Sites.ReadWrite.AllEvery SharePoint site and every OneDrive in the tenantSites.Selected, with site permissions granted one site at a time
Directory.ReadWrite.AllDirectory objects tenant-wide, including group membership and application configuration, though not deletion of users or groupsNarrower object-scoped permissions, or a directory role assigned to the service principal with administrative unit scope
Application.ReadWrite.AllCredentials on every application, so it can authenticate as any of them, though not consent grantsApplication.ReadWrite.OwnedBy, which allows the same operations only on applications the app owns
AppRoleAssignment.ReadWrite.AllPermission grants for any app, user or group, including granting itself further app rolesNo safe narrowing. Remove it and assign the app roles the workload needs directly
RoleManagement.ReadWrite.DirectoryDirectory role membership, which includes Global AdministratorNo safe narrowing. This is administrative control of the tenant
Group.ReadWrite.AllMembership of every group, including the groups that gate access to applications and rolesA directory role scoped to an administrative unit, paired with tenant-wide directory read, instead of the Graph permission

Application permissions to resolve to a named owner before anything else

Client secrets, certificates and who can add another one

An application can authenticate three ways. A client secret is a password the portal generates and displays once, a certificate is stronger and can be rotated from a key store, and a federated credential stores nothing in the directory because an external issuer such as a build pipeline presents a signed token that Entra exchanges for an access token. The portal caps a new client secret at twenty-four months and Microsoft recommends an expiry under twelve, but an existing secret's expiry cannot be edited in place, so shortening one means issuing a replacement and deleting the old credential. Adding a secret does not remove the old one either, so an application with four live secrets and one consumer is either mid-rotation or carrying three that nobody can account for.

The tenant application management policy is the control that stops this recurring, and most tenants have never touched it. It exists in every tenant as a single object, it is disabled by default, and it holds separate restrictions for application objects and for service principal objects, so restricting one does not restrict the other. Microsoft's own recommended settings are stronger than teams expect: disable client secrets and symmetric keys entirely, and cap certificate lifetimes at 180 days. Each restriction also takes a date from which it applies, so a new standard can bind every application registered from today while the existing estate is worked through on a schedule that does not break production.

Owners are the part that gets missed, because an owner can add a credential to an application and authenticate as it with every permission that application holds, and no directory role is required. Microsoft documents the chain in its own role descriptions: Application Administrator and Cloud Application Administrator can add credentials to an application and use them to impersonate its identity, and the Authentication Administrator warnings spell out the two-hop version, where resetting an application owner's credentials leads to the owner and through the owner to a privileged application. The finding worth chasing is usually not somebody's own experiment but the integration holding directory write permissions that gained a second owner during a migration and kept it after that person left. Where somebody needs to manage one application, a directory role assignment scoped to that single app registration does the job without tenant-wide application rights.

From the identity plane into the Azure resource plane

Entra roles and Azure role assignments are separate systems, and an access map drawn from Azure role assignments alone is wrong in a specific way. A Global Administrator holding no Azure role at all can open Microsoft Entra ID properties in the Azure portal, set access management for Azure resources to yes, and be assigned User Access Administrator at the root scope, which covers every management group and subscription in the tenant. The toggle applies only to the user who sets it, so it cannot be flipped for the role as a whole, and Microsoft's guidance is to switch it back off as soon as the work at root scope is finished. The count of Global Administrators is therefore also the count of people who can reach every Azure subscription, whatever the resource-side map says.

Elevation is worth checking rather than assuming. The Azure portal shows a banner on that same properties page stating how many users currently hold elevated access, listing role assignments for User Access Administrator at the root scope returns the same answer from the command line, and the elevation events land in both the Entra audit logs and the Azure activity log. The path runs in the other direction as well, because a service principal holding Contributor on a production subscription with a twenty-four month secret in a pipeline variable is an Azure exposure whose real control lives in the identity plane. Managed identities move that problem rather than removing it: there is no secret to steal, but a managed identity is still a service principal with role assignments, it sits outside the scope of conditional access for workload identities, and a user-assigned identity attached to a compute resource can be used by anyone who can run code on it.

The inventory order that finds the worst thing first

A tenant of any age holds hundreds of service principals, most of them first-party entries and small integrations, and a list sorted by name buries the one that matters. Order the work by consequence instead, so the first two steps isolate the applications that act with no user and hold permissions reaching everything. Everything after that is establishing how each of them got there and whether anyone still owns the answer.

Two patterns come out of that order often enough to expect them. The first is the migration application, created under a deadline, granted every permission the vendor's documentation listed rather than the ones the task needed, and never revisited. The second is the application that has not authenticated in a year and still holds directory write, which is the cheapest finding in the report to close because nothing depends on it any more.

  • Export every service principal with its app role assignments and isolate the ones holding application permissions on Microsoft Graph or Exchange, because those act with no policy in front of them.
  • Within that set, flag the permissions reaching all mail, all files, application credentials or directory roles, and resolve each to a named owner and a stated purpose before touching anything.
  • Pull credentials by type, age, expiry and count, looking for secrets issued at the maximum lifetime and for secrets where a certificate or federated credential would do the same job.
  • List the owners on every application registration and enterprise application, and test each owner against the privilege that application carries rather than against the organisation chart.
  • Read the service principal sign-in log, which is its own tab beside the user sign-in tabs, and match each privileged application to the addresses it actually authenticates from.
  • Finish in the audit log with the ApplicationManagement activities that change this surface: Consent to application, Add service principal credentials, Add owner to application, Add owner to service principal, and Add app role assignment to service principal.

The tenant settings that decide the next grant

User consent has three positions and the middle one carries a task most tenants skip. Users may consent to anything that does not already require administrator consent, they may consent only to applications from verified publishers or registered in your own tenant and only to permissions you have classified as low impact, or user consent is off entirely. The middle position enforces against a classification list you have to populate yourself, so selecting it without classifying anything blocks every consent and produces support tickets rather than security. Microsoft's worked example classifies the minimum set needed for single sign-on, being the openid, profile, email and offline_access delegated permissions on Graph, and only delegated permissions that do not already require administrator consent can be classified at all.

One property of these settings catches teams out. Updates to user consent settings affect future consent operations only, so every grant already in the tenant survives untouched with its permissions and refresh tokens intact, because the setting governs who may create a grant rather than which grants exist. Restricting consent stops the next one and does nothing about the last three years, which is why the inventory comes first. Pair the change with the admin consent workflow, which turns a blocked request into a queue item carrying the requesting user and the permissions asked for, and settle the registration default in the same sitting, because letting every user register applications is defensible in an engineering organisation and harder to defend elsewhere.

What the review leaves behind

The output is a register rather than a list of findings. One row per service principal above a threshold you set, carrying the application name and identifier, the owner as a named person, what it exists to do, permissions marked delegated or app-only, credential type and expiry, date last authenticated, and a decision to keep, scope down, re-credential or remove. The tenant positions sit alongside it with the date each was set, covering the consent setting, the registration setting, the admin consent reviewers and the state of the application management policy. Two habits keep it current: admin consent requests get decided against the register, and the audit activities listed above get alerted somewhere a person reads, because each one is either a deliberate change or the first visible step of an intrusion.

This is the substance of the Entra ID and Azure security reviews we run at Black Shard, and it sits beside conditional access work rather than inside it, because a clean policy set proves nothing about this plane. We build and operate production systems on Azure ourselves, including our own clinical software venture hosted in Australia, so the register we hand a client is the same artefact we keep for our own tenant. Findings come back in plain English with the fix beside each one, and the re-test proves the holes are closed.

Put a security lead at your table.

Australia-wide, from our Brisbane head office. Someone will contact you as soon as possible.

Open a briefinfo@blackshard.com.au