SIEM integrations

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 az CLI, 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 workspace

  • tableName — custom log table name; must end in _CL (Azure enforces this for custom log tables), for example PloyAudit_CL

  • dceName — name for the Data Collection Endpoint

  • dcrName — name for the Data Collection Rule

  • servicePrincipalObjectId — 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 opaque dcr-… immutable ID, not the DCR resource name

  • streamName — the stream declared on the DCR, shaped like Custom-<tableName> (for example Custom-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

  1. In Ploy, go to Integrations → SIEM.

  2. Choose Add new integration, select Microsoft Sentinel, and click Start.

  3. On Details, give the integration a name (for example Production Microsoft Sentinel) and click Next.

  4. 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, the immutableId value)

    • Stream name — Bicep output streamName (starts with Custom-)

  5. 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:

  1. Go to Certificates & secretsFederated credentials.

  2. Click Add credential and choose Other issuer as the scenario.

  3. Paste the Issuer and the Subject identifier that Ploy displays on this step.

  4. Leave the Audience as its pre-filled default (api://AzureADTokenExchange).

  5. 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

  1. Still on the Federation step in Ploy, click Test. On success, Ploy shows Test event sent and posts a synthetic row to your table.

  2. 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 20

Replace PloyAudit_CL with the table name you deployed. The columns Ploy sends are:

Column

Meaning

TimeGenerated

Event time as submitted (Azure may rewrite this—see below)

OccurredAt

Authoritative event time; use this for queries and correlation

EventId

Stable event id; use this to deduplicate

CategoryUid, ClassUid, ClassName, ActivityId, ActivityName, TypeUid

OCSF classification for the event

Action

Ploy action name (test events use ploy.connection_test)

ActorType, ActorId, ActorEmail, ActorName

Who performed the action

Targets

Resources or identities the action affected

Result

Outcome of the action

IpAddress, UserAgent

Request metadata when present

Payload

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 EventId
  • The custom table name must end in _CL.

  • The stream name Ploy expects starts with Custom- and matches the DCR stream (for example Custom-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

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.

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.

  1. In Ploy, open the integration on Integrations → SIEM, then Delete it so delivery stops.

  2. 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 \
      --yes
  3. Delete the Entra app registration (this also removes its service principal and federated credentials):

    az ad app delete --id <appId>

Was this helpful?