Entra workload credential leaked

Severity criticalCloud & SaaSSingle eventstablecloud.identity.entra_workload_credential_leaked · v1.0.0

Microsoft found a SERVICE PRINCIPAL's credential published somewhere public and the detection is still open.

What it detects

Microsoft found a SERVICE PRINCIPAL's credential published somewhere public and the detection is still open.

leakedCredentials is not a behavioural score. Microsoft matches credential material found in public source repositories, paste sites and dark-web dumps against the tenant's own identities. When it fires, a secret that authenticates an application identity is, or was, publicly readable.

This is separated from cloud.identity.entra_workload_identity_risk (high) and raised to critical because of what the credential is:

* A client secret or certificate is a **bearer** credential. Anyone holding it is the application — no second factor, no device, no user interaction, from any address on the internet. * It carries the app's **app-only permissions**, which are commonly tenant-wide. There is no per-user scope limiting the blast radius. * It stays valid until somebody rotates it. Revoking sessions does nothing; disabling a user does nothing. The credential itself has to be removed. * Leaks are usually **historical by the time they are detected** — the secret was committed, the commit was pushed, and the repository may have been public for months. Assume use, then look for it.

The immediate action is rotation, not investigation: remove the credential from the app registration first, then work out what it did while it was valid.

MITRE ATT&CK mapping

  • T1552Unsecured Credentials· Credential Access
  • T1552.001Unsecured Credentials: Credentials In Files· Credential Access
  • T1078.004Valid Accounts: Cloud Accounts· Initial Access

False positives and triage

Very few, and none of them mean "ignore it". Microsoft matches real credential material, so a match is evidence the secret was exposed even if the exposure was brief or the repository has since been made private — the secret is still burned and still has to be rotated.

The realistic false alarm is a STALE detection: a credential leaked, detected, and rotated some time ago, whose record is re-imported with a historical log pull and read as current. Check the detection's timestamp against the case window, and check whether the named credential (keyIds in the preserved payload) still exists on the app registration.

A test or sample credential committed deliberately to a demo repository will also match. That is a real leak of a real credential; the correct response is still rotation, and the lesson is that the demo should not have used a tenant identity.

Do NOT treat "the app looks idle" as reassurance. App-only tokens leave no interactive sign-in trail, so absence of obvious activity is weak evidence. Check the app's own sign-in logs and the Graph activity for the app id.

The rule

Declarative YAML read by the detection engine — data, never executed. Confidence 90%. Source: rules/cloud/entra_workload_credential_leaked.yaml, licensed under the Apache License 2.0.

id: cloud.identity.entra_workload_credential_leaked
version: 1.0.0
status: stable
severity: critical
confidence: 0.9
platforms: [application]
mitre_techniques: [T1552, T1552.001, T1078.004]
description: |
  Microsoft found a SERVICE PRINCIPAL's credential published somewhere public and
  the detection is still open.

  `leakedCredentials` is not a behavioural score. Microsoft matches credential
  material found in public source repositories, paste sites and dark-web dumps
  against the tenant's own identities. When it fires, a secret that authenticates
  an application identity is, or was, publicly readable.

  This is separated from `cloud.identity.entra_workload_identity_risk` (high) and
  raised to critical because of what the credential is:

    * A client secret or certificate is a **bearer** credential. Anyone holding it
      is the application — no second factor, no device, no user interaction, from
      any address on the internet.
    * It carries the app's **app-only permissions**, which are commonly
      tenant-wide. There is no per-user scope limiting the blast radius.
    * It stays valid until somebody rotates it. Revoking sessions does nothing;
      disabling a user does nothing. The credential itself has to be removed.
    * Leaks are usually **historical by the time they are detected** — the secret
      was committed, the commit was pushed, and the repository may have been
      public for months. Assume use, then look for it.

  The immediate action is rotation, not investigation: remove the credential from
  the app registration first, then work out what it did while it was valid.
match:
  provider: AzureAD
  event_action: risk_detection
  ext:azuread.identity_type: service_principal
  ext:azuread.risk_event_type: leakedCredentials
  ext:azuread.risk_state_any:
    - atRisk
correlation_keys: [user_name, source_ip]
false_positive_guidance: |
  Very few, and none of them mean "ignore it". Microsoft matches real credential
  material, so a match is evidence the secret was exposed even if the exposure was
  brief or the repository has since been made private — the secret is still burned
  and still has to be rotated.

  The realistic false alarm is a STALE detection: a credential leaked, detected,
  and rotated some time ago, whose record is re-imported with a historical log
  pull and read as current. Check the detection's timestamp against the case
  window, and check whether the named credential (`keyIds` in the preserved
  payload) still exists on the app registration.

  A test or sample credential committed deliberately to a demo repository will
  also match. That is a real leak of a real credential; the correct response is
  still rotation, and the lesson is that the demo should not have used a tenant
  identity.

  Do NOT treat "the app looks idle" as reassurance. App-only tokens leave no
  interactive sign-in trail, so absence of obvious activity is weak evidence.
  Check the app's own sign-in logs and the Graph activity for the app id.

Related detections

Run this rule on your own logs — offline

KIROSEC runs this rule and the rest of the library over Windows, Linux, macOS and cloud audit logs on the analyst's own machine. Every alert links to the events that raised it, and nothing leaves the device.

Browse all detections