new: Federated Identity Credential Added To Entra Application Or Managed Identity - #6278
Conversation
swachchhanda000
left a comment
There was a problem hiding this comment.
Please do share the relevant logs. thank you
6ae277a to
74f9ec8
Compare
74f9ec8 to
40292fc
Compare
|
Thanks for the review. Below is the audit event this rule is written against, plus the field by field mapping. About the sample: it is a redacted, representative Microsoft Entra ID audit record in the Log Analytics 1. FIC added to an app registration (
|
Rule selection |
Location in the event | Sample 1 | Sample 2 |
|---|---|---|---|
OperationName |
OperationName |
Update application |
Update service principal |
TargetResources.modifiedProperties|contains: 'FederatedIdentityCredentials' |
TargetResources[].modifiedProperties[].displayName |
FederatedIdentityCredentials |
FederatedIdentityCredentials |
Both conditions are ANDed, so the operation name alone is never enough. The rule does not parse the serialized newValue, so the internal key casing of that blob is not load bearing for matching. It is included above because it is what an analyst reads during triage: Issuer and Subject are the two values that decide whether the FIC is legitimate.
Why the second condition is what keeps this specific
A benign Update service principal, for example a display name change, carries no FederatedIdentityCredentials entry, so selection does not fire:
"modifiedProperties": [
{
"displayName": "DisplayName",
"oldValue": "\"example-uami-build\"",
"newValue": "\"example-uami-build-prod\""
}
]Cross checks on the two operation names
- Microsoft's audit activity reference lists both
Update applicationandUpdate service principalunder theApplicationManagementcategory: https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities Azure/Azure-Sentinel,Hunting Queries/AuditLogs/ServicePrincipalFederatedIdentityCredentialAdded.yamlkeys offwhere OperationName in~ ("Update service principal")followed bymv-expand ModProp = TargetResources[0].modifiedProperties | where tostring(ModProp.displayName) =~ "FederatedIdentityCredentials".- Elastic's
persistence_entra_id_service_principal_federated_issuer_modifiedkeys offwhere event.action == "Update application"followed bywhere azure.auditlogs.properties.target_resources.0.modified_properties.0.display_name == "FederatedIdentityCredentials", and dissects"Issuer":"..."out ofnew_value. That is where the serialized shape shown above comes from.
Note for completeness: a FIC created on a user assigned managed identity through ARM (Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/write) is recorded in the Azure activity log, which is a different logsource. The Update service principal branch here covers the directory side of the same technique.
What changed in this push
- Rebased onto current
master, the branch was behind. - Added
logsource.definitiondeclaring the TargetResources mapping requirement, mirroringazure_user_account_mfa_disable.yml, since this rule depends on that array being mapped.
Gates on the updated rule: sigma check --fail-on-error --fail-on-issues --validation-config tests/sigma_cli_conf.yml reports 0 errors and 0 issues (pySigma-validators-sigmahq 0.21.0), tests/test_rules.py 11 OK, tests/test_logsource.py 3 OK, yamllint clean.
Happy to tighten TargetResources.modifiedProperties|contains into the stricter TargetResources.modifiedProperties.displayName form if you prefer it. I kept the |contains shape to stay consistent with azure_ad_certificate_based_authencation_enabled.yml in the same folder.
Match verification
Compiled the rule and ran it against these samples with json_matcher v0.0.2, the checker regression-tests.yml uses:
$ sigma convert -t golang_expr --without-pipeline \
rules/cloud/azure/audit_logs/azure_app_federated_identity_credential_added.yml
(lower(OperationName) == lower("Update application") or lower(OperationName) == lower("Update service principal"))
and lower(TargetResources?.modifiedProperties) contains lower("FederatedIdentityCredentials")
$ ./json_checker -event fic_added.json -expr "$EXPR" -test-type json
MATCH
$ ./json_checker -event display_name_changed.json -expr "$EXPR" -test-type json
NO-MATCH
The events fed to the checker are the ones shown above with TargetResources mapped, which is exactly what the new logsource.definition line asks the backend for. Without that mapping the array does not resolve, which is why declaring it matters here as it does in azure_user_account_mfa_disable.yml.
Summary
New detection rule: Federated Identity Credential Added To Entra Application Or Managed Identity.
Adding a federated identity credential (FIC) establishes workload identity federation — a trust with an external OIDC issuer that can then obtain tokens and authenticate as the target application or service principal without a secret or certificate. An adversary who can modify an application or service principal can add a FIC pointing at an issuer/subject they control (e.g. an attacker-owned GitHub Actions repo) to gain persistence that survives secret and certificate rotation. This is a distinct persistence primitive from adding a password/certificate credential (already covered by
azure_app_credential_added.yml) and from domain federation changes (azure_federation_modified.yml).Detection logic
Fires on the Entra ID audit event for a FIC being added to either object type:
OperationNameisUpdate application(app registration) orUpdate service principal(service principal / managed identity), andTargetResources.modifiedPropertiescontainsFederatedIdentityCredentials.The
modifiedPropertiesdiscriminator is what keeps the rule specific — a benignUpdate service principalevent (e.g. aDisplayNamechange) does not match. Field taxonomy and themodifiedProperties|containspattern mirror the existingazure_ad_certificate_based_authencation_enabled.yml.Verified the exact operation name (
Update service principal) and the modified-property display name (FederatedIdentityCredentials) against a real Entra audit-log sample, plus Microsoft's workload identity federation documentation and dirkjanm's research.MITRE ATT&CK
Notes
Complements a hardening check for the same technique — flagging FICs on privileged applications/service principals — so the preventive and detective sides line up.
Validation
sigma check --validation-config tests/sigma_cli_conf.yml <rule>→ 0 errors, 0 issues (pySigma validators-sigmahq 0.21.0).python3 tests/test_rules.py→ 11 tests OK.python3 tests/test_logsource.py→ 3 tests OK.