In modern cloud intrusions, stealthy persistence has replaced noisy data exfiltration. When an adversary compromises an account with application management privileges in Microsoft Entra ID (such as Application Administrator or Cloud Application Administrator), the immediate objective is securing long-term footholds. MITRE ATT&CK technique T1098.003 (Add OAuth App Credentials) is the weapon of choice: injecting a new client secret or x509 certificate into an existing, trusted enterprise application or Service Principal.
Attack Anatomy: The Silent Enterprise Doorway
Unlike provisioning a rogue Global Administrator account—which promptly triggers privileged identity alarms—tampering with credentials on an already approved enterprise app inherits all associated Microsoft Graph permissions (e.g., Mail.ReadWrite, Directory.ReadWrite.All, Files.ReadWrite.All). The adversary no longer needs interactive authentication. By utilizing the OAuth 2.0 Client Credentials Grant directly from adversary C2 infrastructure, they completely bypass user-focused MFA and Conditional Access policies.
The Entra ID Native Blind Spot
By default, Microsoft 365 audit logs capture credential additions under Add service principal credentials or Update application – Certificates and secrets management. However, these events get submerged beneath hundreds of legitimate CI/CD pipeline rotations and DevOps workflows. Without behavioral correlation tracking caller source IP, identity type (interactive user vs workload identity), and unusual secret lifetime parameters (such as credentials set to expire in 50 or 99 years), the backdoor remains undetected across security audits.
Advanced Hunting Detection (KQL)
The following KQL rule filters out legitimate DevOps automation pipelines to detect suspicious credential creation in real time:
CloudAppEvents
| where ActionType in~ (
"Add service principal credentials.",
"Update application – Certificates and secrets management ")
| extend ActorUPN = tostring(RawEventData.InitiatedBy.user.userPrincipalName),
ActorIP = coalesce(IPAddress, tostring(RawEventData.InitiatedBy.user.ipAddress)),
AppId = tostring(RawEventData.TargetResources[0].id),
AppName = tostring(RawEventData.TargetResources[0].displayName)
| mv-expand Property = RawEventData.TargetResources[0].modifiedProperties
| where Property.displayName =~ "KeyDescription"
| extend KeyData = parse_json(tostring(Property.newValue))
| extend KeyType = tostring(KeyData[0].KeyType), EndUtc = todatetime(KeyData[0].EndDateTime)
| where not(ActorUPN endswith "svc-devops@akuity.eu" and ActorIP in ("51.144.0.0/14"))
| project Timestamp, ActorUPN, ActorIP, AppName, AppId, KeyType, EndUtc, ReportIdAutomated Remediation with Akuity SOC
Once detected, response latency dictates whether exfiltration occurs. Akuity SOC's agentless SOAR orchestration eliminates the persistence window in seconds:
- Friction Elimination: The in-app Akuity SOC AI assistant parses and decodes Graph API payloads in under 2 seconds within the unified Ticket Panel, preventing confidential credential exposure on unvetted online parsers.
- Surgical SOAR Response: One-click execution of
revokeOAuthApp()directly from the evidence canvas to purge the injected secret and immediately revoke Service Principal permissions. - Governance & Compliance: Mandatory step-up authentication via MFA AAL2 and tamper-proof audit trail logging adhering to NIS 2 and SOC 2 Type II assurance frameworks.
Continuously audit Service Principal credential injections and sever rogue API access in one click with agentless cloud SOAR.
Start your 14-day free trial (no credit card required) →Technical FAQ
Why does Conditional Access fail to block this activity?
The OAuth 2.0 Client Credentials grant used by applications operates non-interactively without user context. Traditional Conditional Access policies apply exclusively to human sessions unless dedicated Entra Workload ID conditional policies are explicitly configured and licensed.
How do you differentiate malicious injections from routine Terraform runs?
Verification relies on the initiating identity (interactive admin account vs managed DevOps identity), origin IP ranges, and secret validity timestamps matched against pipeline deployment windows.