SERVICE PRINCIPAL
CLIENT SECRET
APP CREDENTIALS
T1098.001
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting Service Principal and App Credential Abuse

Service principals have no MFA, no device and often no owner. An attacker who adds a secret to an existing one gets a durable, quiet identity.

Scroll

Applications authenticate with secrets or certificates, so anyone who can add a credential to an app with strong permissions can sign in as that app. This route needs no user password, and the resulting sign-ins appear in service principal logs that many teams do not monitor. The two events to connect are the credential addition and the first sign-in that uses it.

Signals at a Glance

SignalWhereATT&CK
Client secret or certificate added to an existing app or service principalEntra AuditLogsT1098.001
Credential added by a user or app that does not normally manage that appEntra AuditLogsT1098.001
First sign-in of the app from a new IP, ASN or country after the additionAADServicePrincipalSignInLogsT1078.004
High-privilege app role assigned to a service principalEntra AuditLogsT1098.003
App reading mail, files or directory data in bulkGraph activity logsT1528

Credential Additions

Entra records the addition of credentials under Update application – Certificates and secrets management and Add service principal credentials. Surface every addition, enriched with the app’s role and the actor:

// Microsoft Sentinel (KQL) - credentials added to apps and service principals
AuditLogs
| where OperationName in ("Update application - Certificates and secrets management",
                          "Update application – Certificates and secrets management",
                          "Add service principal credentials",
                          "Update service principal")
| where Result =~ "success"
| extend App = tostring(TargetResources[0].displayName),
         AppObjectId = tostring(TargetResources[0].id),
         ActorUser = tostring(InitiatedBy.user.userPrincipalName),
         ActorApp = tostring(InitiatedBy.app.displayName),
         ActorIp = tostring(coalesce(InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))
| project TimeGenerated, OperationName, App, AppObjectId, ActorUser, ActorApp, ActorIp
| order by TimeGenerated desc
// tune/validate: operation display names vary slightly; list distinct OperationName values for Category == ApplicationManagement in your tenant

First Use of the New Credential

The addition becomes much more convincing when the same app then signs in from somewhere new. Compare recent app sign-ins against each app’s own history:

// KQL - service principal sign-ins from IPs not seen in the prior 30 days
let history = AADServicePrincipalSignInLogs
    | where TimeGenerated between (ago(30d) .. ago(1d)) and ResultType == 0
    | distinct ServicePrincipalId, IPAddress;
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(1d) and ResultType == 0
| join kind=leftanti history on ServicePrincipalId, IPAddress
| summarize SignIns = count(), Resources = make_set(ResourceDisplayName, 10), First = min(TimeGenerated)
          by ServicePrincipalId, ServicePrincipalName, IPAddress, AppId
| order by SignIns desc
// tune/validate: SaaS vendors rotate egress ranges; allowlist them by AppId or by published IP ranges
Vetted sources

Use Microsoft’s guidance on securing workload identities, Microsoft Sentinel service principal analytics, Elastic and SigmaHQ Azure application rules, and Microsoft’s incident response playbook for application compromise. Baseline your own environment first, as DevOps pipelines rotate secrets constantly.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026