A service principal is the identity an application uses inside one specific tenant (one organization’s directory). It is the local record that says “this app exists here, and this is what it may do,” and it signs in with its own credential, with no human user involved. Identity management as a service products such as Microsoft Entra ID, Okta, Auth0 and managed Keycloak all need some version of this idea, because every backup tool, sync job and security scanner that touches your data needs an identity of its own. The term as used here is Microsoft’s, but the audit problem it creates is general: the vendor apps you have approved can act without any person present, so they deserve a regular review.
This post explains what a service principal is, how vendor apps end up with broad app-only access, how to audit them, and how the same model looks in Keycloak. It uses the October 2026 ConnectWise (SkyKick) incident reported by Huntress as a worked example. The incident was still developing when this was written (17 October 2026), so check Huntress’s post for later updates.
Key Takeaways
- A service principal is an app’s identity in one tenant, separate from the app’s global registration and from any user.
- App-only sign-ins involve no user and no MFA prompt, so the credential and its permissions are the main defense.
- Audit enterprise apps, their permissions, their credentials and their service principal sign-ins on a schedule.
- Disabling a compromised app does not remove credentials an attacker already added elsewhere.
What is a service principal?
Microsoft’s documentation, “Apps & service principals in Microsoft Entra ID” (Microsoft Learn), defines two related objects. The application object is the global definition of an app and lives in the tenant where it was registered, which Microsoft calls its home tenant. A service principal is the local representation of that app, a concrete instance created in every tenant where the app is used.
The distinction matters because the two objects answer different questions. The application object describes the software, while the service principal in your tenant defines what that software can do in your environment, through the permissions your administrators consented to. According to the same page, a multitenant application gets a service principal in each tenant where a user from that tenant has consented to its use. When a vendor sells one product to a thousand customers, there is one application object at the vendor and a thousand service principals, one per customer tenant.
A service principal is also not a user account and not the same thing as a service account in the older, Active Directory sense. Microsoft’s guide “Introduction to securing Microsoft Entra service accounts” lists service principals as one of three kinds of non-human account in Entra, next to managed identities and user-based service accounts, and recommends a managed identity or a service principal over a regular user account.
How does app-only access work?
App-only access means the application authenticates as itself instead of acting on behalf of a signed-in person. Microsoft Learn describes the OAuth 2.0 client credentials grant as letting a service use its own credentials, instead of impersonating a user, and says it is commonly used for server-to-server work that runs in the background without immediate user interaction.
In practice the vendor’s software presents a secret, a certificate or a federated assertion (a signed statement from another trusted issuer) to the identity provider, and gets back an access token. The permissions in that token are the application permissions an administrator already granted, and nobody is asked to approve anything at sign-in time. Huntress put the consequence plainly in 2026: for an Entra application, a client secret and a certificate are both ways to prove identity, either one gives the holder the same access from anywhere, and app-only sign-ins involve no user, no device and no MFA prompt (Huntress, “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, October 2026).
This means the credential and the permissions it unlocks carry most of the protection for this kind of identity. A password with MFA has a second factor, but a vendor application credential has nothing comparable in front of it. Microsoft Entra Conditional Access for workload identities can restrict where an app signs in from, but Microsoft’s documentation, “Conditional Access for workload identities” (Microsoft Learn), says it covers only single-tenant service principals registered in your own tenant and does not cover third-party SaaS and multitenant apps, and it needs a Workload Identities Premium license. For vendor apps, your main controls are the permissions you consented to, monitoring of their service principal sign-ins, Microsoft Entra ID Protection (which, according to Microsoft Learn’s “Securing workload identities”, detects risk on single tenant, non-Microsoft SaaS and multitenant apps), and the removal of apps you no longer use.
Why do vendor apps accumulate broad permissions?
Backup, sync and security tools need to read a great deal to do their job, so customers consent to a lot. In its October 2026 post, Huntress described ConnectWise Cloud Backup (formerly SkyKick) as a service for managed service providers that is granted broad access to mailboxes, OneDrive, SharePoint, Teams and directory data in every tenant where it is installed.
The incident shows how that plays out. According to Huntress, a credential belonging to ConnectWise Cloud Backup was compromised and used on 15 October 2026 to obtain Microsoft Graph access tokens in customer Microsoft 365 tenants from a hosting provider address, 144.172.64[.]128, rather than from the Azure private address space the app normally uses. Huntress confirmed unauthorized sign-ins in 162 tenants as of 19:00 UTC on 16 October. In its 17 October update at 5:15 PM ET, it reported almost 1,000 Entra tenants with sign-in activity from that address, over 300 of which succeeded, and noted that attempts failed in tenants where the relevant service principal was not present.
That last detail is the practical argument for an audit. A stolen vendor credential works against every tenant where the vendor’s app has a service principal, and it fails where there is none. Removing a vendor app you no longer use therefore reduces your exposure directly.
How does an attacker stay inside after the vendor app is disabled?
An attacker can add new credentials to other applications, which keeps working after the original app is disabled. Huntress documented one tenant where a second ConnectWise application, ConnectWise Cloud Management for Microsoft Teams, added itself to the Global Administrator role and then added new client secrets to two other applications, an MSP management application and Huntress’s own application. The new secrets were set to expire in 2028, and the whole sequence took about five minutes. Huntress’s later update places this earlier activity in Microsoft’s private Azure IPv6 space, which legitimate ConnectWise traffic also uses, so the address does not identify who did it, and Huntress says it has not tied this phase to the same operator as the token sweep from 144.172.64[.]128. Its 17 October update says ConnectWise has told Huntress it disabled the relevant applications on its side.
Huntress also warned that disabling the abused ConnectWise apps does not remove credentials that were already added, so customers must review the credentials on all of their Microsoft 365 applications. MITRE ATT&CK describes the same pattern as sub-technique T1098.001, additional cloud credentials, and notes that APT29 added credentials to OAuth applications and service principals during the SolarWinds compromise (MITRE, “Account Manipulation: Additional Cloud Credentials”). The detection guidance on that page is to watch for credentials added to existing service principals or applications by non-standard identities or IP ranges.
How do you audit the service principals in your tenant?
The audit has five parts, and you can do it in an afternoon for a small tenant. The goal is a list of every app that can act without a person, with an owner who can explain why it needs what it has.
- List the apps. In Entra, that is the Enterprise applications view, which is where Huntress tells customers to search for the affected application IDs. Record each app and its publisher, and find when it was consented to in the “Consent to application” audit event, since the list itself only shows when the app was created.
- Review permissions and roles. For each app, list the application permissions it holds and any directory roles assigned to its service principal. If a backup tool holds a directory administrator role, ask the vendor why it needs one.
- Review credentials. List the secrets and certificates with their creation and expiry dates, and ask who added each one. Check two places: the App registrations in your tenant, and the password and key credentials on every service principal, which you can read through Microsoft Graph or PowerShell because credentials can be added directly to a service principal and are easy to miss in the portal. A vendor’s own secret for a multitenant app lives on its application object in the vendor’s home tenant, so you cannot see or rotate it from your tenant; that is why unexpected credentials appearing in your tenant stand out.
- Read the right logs. Microsoft Learn’s sign-in log documentation lists service principal sign-ins as a separate category from interactive and non-interactive user sign-ins, so a search through the default user sign-in view will not show app-only activity. Look at the service principal view for logins from addresses the vendor does not normally use.
- Assign an owner. An app nobody on your team can explain is the first candidate for removal.
Keep the limits of the logs in mind. Huntress noted that Microsoft’s audit log for app-only actions carries no source IP, does not record the details of an added credential, and does not record what an application read through Microsoft Graph. Confirming what was added therefore means querying Graph for the current credentials on each application and service principal, and using the audit log to see when they changed, rather than relying on the portal summary alone.
What should you do if a vendor app is compromised?
Disable the application rather than deleting it, remove anything it planted, and rotate credentials. That order follows Huntress’s own guidance, which says to disable application IDs and not delete them, and not to re-enable affected ConnectWise applications until ConnectWise confirms all credentials have been reset. Huntress’s reason is that deleting the app removes the consent, so you would have to consent again to restore the service, while disabling leaves the app and its configuration in place for inspection.
A workable playbook looks like this:
- Disable the vendor service principal and any sibling apps from the same vendor that you cannot verify.
- Review role assignments on every service principal and remove directory roles that were not there before.
- List credentials on all applications, not just the vendor’s, and remove any you cannot attribute to a known change.
- Search service principal sign-ins and audit entries for the incident window, using the addresses and times the vendor or researchers publish.
- Ask the vendor what data they hold for you and what restore options exist, since Huntress notes that disabling an app does not change backups the vendor has already stored.
How does the same model work in Keycloak?
Keycloak has the same concept under different names. In Keycloak, every client can have a built-in service account, which the Keycloak server administration guide describes as allowing the client to obtain an access token. A confidential client (one that must authenticate) with the service accounts option turned on is the closest equivalent to a service principal using the client credentials grant. Our guide to machine-to-machine authentication in Keycloak walks through setting one up.
The audit translates directly. List confidential clients, check which have service accounts enabled, review the roles mapped to each service account, and record an owner and the last time the secret was rotated. Our post on the Storm-3168 service principal secret attacks lists the Keycloak controls in more detail, including signed JWT client authentication, where Keycloak holds only a public key, and federated client authentication, which is supported from Keycloak 26.6 and lets a client authenticate with a token from a trusted issuer instead of a standing secret. For containment, you can disable a client, regenerate its secret and set a not-before time to invalidate tokens already issued (this only helps where Keycloak sees the token, through introspection or a not-before push to the client, so keep service account access token lifetimes short for APIs that validate JWTs locally), and CLIENT_LOGIN events record client credentials sign-ins when event storage is on (see our audit logs feature).
For workloads that you run yourself, the better answer is often to remove the long-lived secret entirely, which our post on workload identity federation with SPIFFE and Keycloak covers. For the human side of third-party consent, see OAuth grant sprawl, and for agents see non-human identity and AI agents in Keycloak.
What does a quarterly vendor app review look like for a small team?
A small team can keep this manageable with one recurring review and a short list of questions per app. Once a quarter, and again after any public vendor incident, go through every enterprise app and confirm the following:
- The business owner still uses the product.
- The permissions and directory roles match what the vendor documents for the current feature set.
- Every credential has a known creator and an expiry date, and none is missing from your record.
- Service principal sign-ins come from the vendor’s usual addresses.
- Unused apps are removed, because an app that is not in your tenant cannot be signed into with a stolen vendor credential.
The same list works for just-in-time access thinking, since permissions an app only needs occasionally are better granted for a window than held permanently. It also helps to know where this sits relative to privileged access tooling, which our post on IAM versus PAM explains.
Frequently asked questions
What is the difference between an app registration and a service principal?
An app registration, which creates the application object, is the global definition of the app in its home tenant. A service principal is the local instance of that app in each tenant where it is used, and it carries the permissions that tenant’s administrators granted. Microsoft Learn describes the first as the template and the second as the concrete instance.
What is the difference between a service account and a service principal?
A service account is a general term for a non-human account used by software. In Microsoft Entra, a service principal is one specific type, and Microsoft’s service account guidance lists it alongside managed identities and user-based service accounts. Keycloak uses the term service account for the built-in identity of a confidential client.
Does MFA protect a service principal?
No. App-only sign-ins involve no user, so there is no interactive prompt to complete. Huntress states that these sign-ins involve no user, no device and no MFA prompt. Protection comes from the credential itself, its rotation, the permissions behind it and monitoring of where it is used.
Should I delete a compromised vendor app?
Disable it first. Huntress advises disabling application IDs rather than deleting them, and keeping them disabled until the vendor confirms every credential has been reset. Disabling also does not remove credentials that were already added to other applications, so review those separately.
How often should I review vendor apps?
Quarterly is a reasonable baseline for a small team, plus an extra review whenever a vendor you use is named in an incident. The review should cover permissions, directory roles, credentials and service principal sign-ins for every app that can act without a person.
Sources
- Huntress, “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, published 16 October 2026 and updated 17 October 2026, retrieved 2026-10-18, https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access
- Microsoft Learn, “Apps & service principals in Microsoft Entra ID”, retrieved 2026-10-18, https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals
- Microsoft Learn, “OAuth 2.0 client credentials flow on the Microsoft identity platform”, retrieved 2026-10-18, https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow
- Microsoft Learn, “Introduction to securing Microsoft Entra service accounts”, retrieved 2026-10-18, https://learn.microsoft.com/en-us/entra/architecture/secure-service-accounts
- Microsoft Learn, “Sign-in logs in Microsoft Entra ID”, retrieved 2026-10-18, https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins
- MITRE ATT&CK, “Account Manipulation: Additional Cloud Credentials (T1098.001)”, retrieved 2026-10-18, https://attack.mitre.org/techniques/T1098/001/
- Keycloak, Server Administration Guide, retrieved 2026-10-18, https://www.keycloak.org/docs/latest/server_admin/