The federated credential issuer, subject, or audience does not match what Ploy presents, or the Application (client) ID is wrong. Confirm the credential uses the exact Issuer and Subject identifier from the Federation step, leave Audience as the pre-filled default, and enter the app (client) ID—not the service principal object ID—in Ploy. Role assignments and federated credentials can take up to 15 minutes to propagate; wait and retry.
Set up Microsoft Sentinel SIEM export
Ploy streams your organization's audit log into your own Log Analytics workspace through the Azure Monitor Logs Ingestion API. Ploy uses OIDC workload identity federation with your Entra app registration for authentication into your Azure account.
Before you start
You need these in place before you configure the integration:
An existing Log Analytics workspace.
The
azCLI, logged in, with permission to deploy resources and a role assignment in the target resource group.An Entra admin who can create an app registration and add a federated credential.
A Ploy admin who can open Integrations → SIEM and create a Microsoft Sentinel integration.
Work through the Azure steps first, then finish federation in Entra after Ploy shows your Issuer and Subject identifier. The subject is the integration id, so it only appears after you save the connection details in Ploy.
Step 1: Entra app registration
Create a single-tenant app registration and service principal in Entra. Do not create a client secret. You will add a federated credential in Step 3 after Ploy shows the issuer and subject.
Capture these three values:
Directory (tenant) ID — your Entra tenant ID
Application (client) ID — the app registration’s client ID (this is what you enter in Ploy)
Service principal object ID — the object ID of the service principal for that app (this is what the Bicep template uses for the role assignment)
App ID vs service principal object ID. The application (client) ID goes into Ploy for token exchange. The service principal object ID receives Monitoring Metrics Publisher on the Data Collection Rule. They are different values; mixing them up breaks the role assignment or token exchange.
Step 2: Deploy the Azure resources
Deploy Ploy's Bicep template into the resource group that holds your Log Analytics workspace. The template provisions the custom log table, a Data Collection Endpoint (DCE), a Data Collection Rule (DCR), and a Monitoring Metrics Publisher role assignment on the DCR for the service principal from Step 1.
Download the template (ploy-sentinel.bicep) and save it locally.
Parameters:
workspaceName— name of your existing Log Analytics workspacetableName— custom log table name; must end in_CL(Azure enforces this for custom log tables), for examplePloyAudit_CLdceName— name for the Data Collection EndpointdcrName— name for the Data Collection RuleservicePrincipalObjectId— the service principal object ID from Step 1
location and tags are optional. location defaults to the resource group's region; keep the DCE and DCR in the same region as the workspace (override location if the workspace is not in that region).
Deploy with a deployment stack so teardown stays clean:
az stack group create \
--name ploy-sentinel-export \
--resource-group <resource-group> \
--template-file ploy-sentinel.bicep \
--action-on-unmanage deleteResources \
--deny-settings-mode none \
--parameters \
workspaceName=<workspace-name> \
tableName=PloyAudit_CL \
dceName=<dce-name> \
dcrName=<dcr-name> \
servicePrincipalObjectId=<servicePrincipalObjectId>If you prefer a one-shot deployment instead of a stack:
az deployment group create \
--resource-group <resource-group> \
--template-file ploy-sentinel.bicep \
--parameters \
workspaceName=<workspace-name> \
tableName=PloyAudit_CL \
dceName=<dce-name> \
dcrName=<dcr-name> \
servicePrincipalObjectId=<servicePrincipalObjectId>After the deploy succeeds, capture these outputs—you will paste them into Ploy:
dceIngestionEndpoint— the DCE logs-ingestion URL (must be HTTPS and end with.ingest.monitor.azure.com)dcrImmutableId— the opaquedcr-…immutable ID, not the DCR resource namestreamName— the stream declared on the DCR, shaped likeCustom-<tableName>(for exampleCustom-PloyAudit_CL)
If Ploy later adds columns to the event schema, redeploy the DCR from the updated template. Azure silently drops any field the DCR does not declare, so an outdated rule will accept events but lose new columns.
Step 3: Connect Ploy and finish federation
Enter the Azure values in Ploy, copy the federation identifiers Ploy generates, then add the federated credential on your app registration and enable delivery.
Enter connection details in Ploy
In Ploy, go to Integrations → SIEM.
Choose Add new integration, select Microsoft Sentinel, and click Start.
On Details, give the integration a name (for example
Production Microsoft Sentinel) and click Next.On Connection, fill in the fields from Steps 1 and 2:
Directory (tenant) ID —
<tenantId>Application (client) ID —
<appId>Data collection endpoint URL — Bicep output
dceIngestionEndpoint(from the DCE overview this is the Logs ingestion URI)DCR immutable ID — Bicep output
dcrImmutableId(from the DCR JSON view, theimmutableIdvalue)Stream name — Bicep output
streamName(starts withCustom-)
Click Next. Ploy saves the integration and opens the Federation step.
Add the federated credential
On the Federation step, Ploy shows an Issuer and a Subject identifier. These are public identifiers, not secrets. Still in your app registration in the Microsoft Entra admin center:
Go to Certificates & secrets → Federated credentials.
Click Add credential and choose Other issuer as the scenario.
Paste the Issuer and the Subject identifier that Ploy displays on this step.
Leave the Audience as its pre-filled default (
api://AzureADTokenExchange).Save the credential.
This lets Ploy authenticate with a signed token instead of a shared secret. No client secret is created.
Test and enable delivery
Still on the Federation step in Ploy, click Test. On success, Ploy shows Test event sent and posts a synthetic row to your table.
Click Enable delivery to start streaming live audit events.
Role assignments and federated credentials can take up to 15 minutes to propagate in Azure. If Test fails right after you deploy the Bicep template or save the credential, wait and retry before changing configuration.
Verifying it works
After a successful test (or once delivery is enabled), query the custom table in your Log Analytics workspace or Sentinel.
PloyAudit_CL
| order by OccurredAt desc
| take 20Replace PloyAudit_CL with the table name you deployed. The columns Ploy sends are:
Column | Meaning |
|---|---|
| Event time as submitted (Azure may rewrite this—see below) |
| Authoritative event time; use this for queries and correlation |
| Stable event id; use this to deduplicate |
| OCSF classification for the event |
| Ploy action name (test events use |
| Who performed the action |
| Resources or identities the action affected |
| Outcome of the action |
| Request metadata when present |
| Additional event detail (internal keys stripped) |
Query and delivery rules
Keep these rules in mind when you build Sentinel analytics or dashboards on Ploy data.
Query and correlate on OccurredAt, not TimeGenerated. Azure Monitor rewrites TimeGenerated to the ingestion time when an event is more than about two days old. The first delivery backfills existing audit history, so every backfilled row can land at “now” on the TimeGenerated axis. OccurredAt is a custom column Azure never rewrites and always holds the true event time.
Delivery is at-least-once. A retry can resend events that already landed. Deduplicate on EventId:
PloyAudit_CL
| summarize arg_min(TimeGenerated, *) by EventIdThe custom table name must end in
_CL.The stream name Ploy expects starts with
Custom-and matches the DCR stream (for exampleCustom-PloyAudit_CL).When the event schema gains columns, redeploy the DCR from the updated template or Azure drops the new fields silently.
Troubleshooting
Ploy surfaces these messages when Test fails. Fix the matching Azure side, then test again.
Could not authenticate with your Entra tenant — check the federated credential and client id
DCR or stream not found — check the immutable id and stream name
The DCR immutable ID must be the opaque dcr-… value from the DCR JSON view (or Bicep output dcrImmutableId), not the DCR display name. Stream name must match the stream on that DCR exactly, including the Custom- prefix.
The app registration is missing Monitoring Metrics Publisher on the DCR
The service principal tied to your app registration needs the Monitoring Metrics Publisher role on the Data Collection Rule. Redeploy the Bicep template with the correct servicePrincipalObjectId, or assign that role on the DCR manually. Role assignments can take up to 15 minutes to propagate; wait and retry before redeploying.
Could not deliver a test event to your Log Analytics workspace — check the ingestion endpoint
Data collection endpoint URL must be the DCE Logs ingestion URI: HTTPS and ending in .ingest.monitor.azure.com. Copy it from the DCE overview or from Bicep output dceIngestionEndpoint.
The data collection endpoint must be an HTTPS Azure Monitor ingestion URL
Ploy rejected the endpoint shape before calling Azure. Use the logs-ingestion host from your DCE (ending in ingest.monitor.azure.com), not the Log Analytics workspace portal URL or a non-HTTPS value.
Teardown
Remove Azure resources and the Entra app when you retire the integration.
In Ploy, open the integration on Integrations → SIEM, then Delete it so delivery stops.
Delete the deployment stack (or the individual resources if you did not use a stack):
az stack group delete \ --name ploy-sentinel-export \ --resource-group <resource-group> \ --action-on-unmanage deleteResources \ --yesDelete the Entra app registration (this also removes its service principal and federated credentials):
az ad app delete --id <appId>