Skip to content

Forward Capsule Security alerts into Microsoft Sentinel so your SOC can triage AI agent and shadow-AI signals alongside the rest of your security telemetry.

Overview

Capsule sends policy-violation alerts into your Microsoft Sentinel workspace via the Azure Monitor Logs Ingestion API, writing each alert as a row in a custom Log Analytics table (CapsuleAlert_CL) on your Sentinel-enabled workspace. From there, your existing Sentinel analytics rules and incident workflows can act on Capsule alerts.

Capsule authenticates as an approved Microsoft Entra ID application using the client-credentials flow. The application is granted a single, narrowly scoped Azure role on the data collection rule - it cannot read your workspace, query data, or access anything else in your tenant.

Capsule policy violation
  → Capsule sends to your Data Collection Endpoint
  → Data Collection Rule routes the record
  → CapsuleAlert_CL table in your Log Analytics workspace
  → Microsoft Sentinel analytics rules / incidents

There are two ways to set this up. First authorize the Capsule application, then pick one:

Prerequisites

Before you begin, ensure you have:

  • Microsoft Sentinel enabled on a Log Analytics workspace
  • Azure permissions to create a Data Collection Endpoint, a Data Collection Rule, and a custom table - typically Monitoring Contributor (or Contributor) on the resource group
  • The ability to assign Azure RBAC roles on the data collection rule - User Access Administrator or Owner
  • A Microsoft Entra ID account with Application Administrator or Global Administrator role (to grant admin consent to the Capsule application)
  • A Capsule Security account with admin access

Authorize the Capsule application

Do this first. Both Quick Setup and the manual flow assign a role to the Capsule application's service principal, so that principal must already exist in your tenant. Authorizing the app creates its service principal; Capsule then needs the principal's Object ID to scope the publishing role.

In Capsule, go to Settings → Notifications, open the Microsoft Sentinel connection dialog, and click Provision Capsule application. You'll be redirected to Microsoft to approve an admin-consent prompt - sign in as Application Administrator or Global Administrator and click Accept. Capsule materializes the service principal and captures its Object ID for you, then shows it in the dialog. You no longer copy any GUID by hand: the captured Object ID is the principalId Quick Setup asks for (and the principal the manual role assignment targets).

If you're not an Entra admin, or you've already authorized the Capsule app in this tenant (for example via the manual flow below on a previous install), check Skip - already authorized in the dialog to proceed without re-running consent. Then provide the existing service principal Object ID where the template or manual steps ask for it (read it with the az ad sp show command below).

Use this only when you can't complete the portal flow (no portal access yet, or you prefer the CLI). The Capsule Sentinel application requests no Microsoft Graph permissions beyond the read access needed to look up its own service principal, so consent simply materializes the principal. Ask your Capsule contact for the Capsule application (client) ID first.

Option A - Admin-consent link (browser). Open the following URL, replacing {TENANT_ID} with your Microsoft Entra tenant ID (Entra ID → Overview → Tenant ID) and {CAPSULE_APP_ID} with the application ID from Capsule. Sign in as Application Administrator or Global Administrator and click Accept:

https://login.microsoftonline.com/{TENANT_ID}/adminconsent?client_id={CAPSULE_APP_ID}

Option B - Azure CLI.

# Create the Capsule application's service principal in this tenant
az ad sp create --id {CAPSULE_APP_ID}

If the service principal already exists you'll see an "already exists" error - that's harmless, continue.

Read the service principal Object ID (the principalId Quick Setup asks for, and the principal the manual role assignment targets):

az ad sp show --id {CAPSULE_APP_ID} \
  --query "{appId:appId, objectId:id, displayName:displayName}" -o jsonc

The objectId field is the value you supply as principalId.

Use the objectId, not the appId. These are different GUIDs. The role assignment targets the service principal's Object ID (objectId) - the application (client) ID (appId) is not interchangeable. Supplying the wrong GUID as principalId still deploys successfully, but Capsule then fails to publish with a runtime 403 because the role was granted to the wrong (or a non-existent) principal. To find the Object ID in the portal instead: Entra ID → Enterprise applications, select the Capsule app, and copy Object ID (not Application ID) from its Overview. (When you provision from the Capsule portal above, this value is captured for you.)


Instead of creating each resource by hand, deploy everything with a single one-click ARM template. It provisions a Data Collection Endpoint, a Data Collection Rule, the CapsuleAlert_CL custom table on your existing workspace, and the least-privilege Monitoring Metrics Publisher role assignment scoped to the rule - all in a new capsule-sentinel-rg resource group.

Authorize the Capsule application first - the template assigns a role to the Capsule service principal, so the principal must already exist or the deployment fails with PrincipalNotFound.

You provide two values:

  • Workspace resource ID - the full ARM resource ID of your existing Sentinel-enabled Log Analytics workspace, in the form /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<name>. To find it in the Azure portal: open Log Analytics workspaces, select your workspace, then in its left menu go to Settings → Properties and copy the Resource ID field. From the CLI: az monitor log-analytics workspace show -g <rg> -n <name> --query id -o tsv.

    Not the "Workspace ID". The workspace Overview page shows a Workspace ID that is a bare GUID (e.g. xxxxxxxx-xxxx-...) - that is not what this field needs. Use the full slash-delimited Resource ID from the Properties page. Pasting the GUID fails deployment validation with The template variable 'workspaceSubId' is not valid… index '2' is out of bounds.

  • Capsule service principal Object ID - the objectId from Authorize the Capsule application. Use the service principal's Object ID, not the application (client) ID - a wrong-but-valid GUID deploys cleanly and only surfaces later as a runtime 403.

Deploy with the Azure portal (browser)

Deploy to Azure

On the custom-deployment pane:

  1. Subscription - select the subscription where the new capsule-sentinel-rg resource group will be created (typically the one containing your workspace).
  2. Region - choose the region for the resource group, Data Collection Endpoint, and Rule (commonly your workspace's region).
  3. Principal Id - paste the service principal Object ID.
  4. Workspace Resource Id - paste your workspace's full ARM resource ID.
  5. Leave Resource Group Name, Dce Name, and Dcr Name at their defaults unless you have a naming convention.
  6. Click Review + create, then Create. Deployment takes one to two minutes.

Deploy with the Azure CLI

az deployment sub create \
  --name capsule-sentinel-integration \
  --location <your-region> \
  --template-uri "https://capsule-security-us-east-1-public-demo.s3.us-east-1.amazonaws.com/microsoft-sentinel/capsule-sentinel-integration.json" \
  --parameters principalId="<service-principal-object-id>" \
               workspaceResourceId="/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<name>"

Read the four connection values straight from the deployment outputs (this --name matches the CLI deploy above; a browser deploy is named Microsoft.Template-<timestamp> instead - see below):

az deployment sub show --name capsule-sentinel-integration \
  --query "properties.outputs.{azureTenantId:azureTenantId.value, dceUri:dceUri.value, dcrImmutableId:dcrImmutableId.value, streamName:streamName.value}" -o jsonc

Enter the connection values in Capsule

The four connection values are exposed as deployment outputs once the deployment succeeds (a failed deployment produces none).

  • Browser deploy: on the deployment-complete page, select Outputs in the left menu. (If you've navigated away: the template deploys at subscription scope, so the outputs live on the subscription deployment - open Subscriptions → your subscription → Settings → Deployments, find the deployment named Microsoft.Template-<timestamp>, then Outputs. They are not under the capsule-sentinel-rg resource group's Deployments blade, which only lists the nested module deployments.) Note that the portal names the deployment Microsoft.Template-<timestamp>, not capsule-sentinel-integration - so the CLI show --name capsule-sentinel-integration above only works if you deployed with the CLI. To read a browser deploy's outputs from the CLI, list the deployments first and use the actual name:

    az deployment sub list --query "reverse(sort_by([?contains(name,'Template')], &properties.timestamp))[0].name" -o tsv
  • CLI deploy: use the az deployment sub show command above.

In Capsule, go to Settings → Notifications, find Microsoft Sentinel, click Set up, and copy in the four values:

Capsule fieldDeployment output
Directory (tenant) IDazureTenantId
Data Collection Endpoint URIdceUri
DCR immutable IDdcrImmutableId
Stream namestreamName

Then click Test Connection and link your policies, as described in Configure the integration in Capsule. You're done - skip Option 2.


Option 2: Manual setup

Create each Azure resource yourself instead of using the Quick Setup template. Authorize the Capsule application first - it's required either way.

1. Create the custom table

In your Sentinel-enabled Log Analytics workspace, create a custom table named CapsuleAlert_CL with the schema below. The Logs Ingestion API requires a TimeGenerated column of type datetime.

ColumnTypeDescription
TimeGenerateddatetimeWhen the violation occurred
TitlestringAlert title
DescriptionstringAlert detail
SeveritystringInformational, Low, Medium, or High
PolicyNamestringThe Capsule policy that triggered the alert
EntityNamestringThe affected agent or resource
SourceUrlstringDeep link back into the Capsule portal
CapsuleTenantIdstringYour Capsule tenant identifier
PolicyIdstringCapsule policy identifier
EntityIdstringCapsule entity identifier
IssueIdstringCapsule issue identifier
AdditionalContextdynamicRemaining alert metadata as JSON

2. Create a Data Collection Endpoint

Create a Data Collection Endpoint (DCE) in the same region as your workspace. After creation, record its Logs Ingestion URI - Capsule sends alerts to this address.

3. Create a Data Collection Rule

Create a Data Collection Rule (DCR) that validates incoming alerts and routes them to the custom table.

  1. Associate the DCR with the endpoint from step 2.
  2. Define an input stream for the schema from step 1. The stream must resolve to Custom-CapsuleAlert_CL - when creating the DCR by hand, Azure prepends Custom- to the name you enter, so type CapsuleAlert_CL and confirm the resulting stream is Custom-CapsuleAlert_CL (this is the value you enter as the Stream name in step 5).
  3. Set the destination to your Log Analytics workspace, output table CapsuleAlert_CL.
  4. A pass-through transformation (source) is sufficient unless you want to reshape rows.

After creation, record the DCR's immutable ID (for example, dcr-xxxxxxxxxxxxxxxx).

4. Assign the publishing role

The Capsule application's service principal already exists from authorizing the Capsule application. Now grant it the single role it needs to publish alerts, scoped to the data collection rule from step 3:

RoleRole definition IDScope
Monitoring Metrics Publisher3913510d-42f4-4e42-8a64-420c390055ebThe data collection rule (DCR)

This is the only permission Capsule requires:

  • No Microsoft Graph permissions are needed. Log ingestion uses the Azure Monitor data plane (https://monitor.azure.com), not Microsoft Graph - so the application requests no mailbox, directory, or device permissions.
  • Scope the role to the DCR, not the subscription. Following least privilege, the Monitoring Metrics Publisher role only allows Capsule to publish records through that rule; it cannot read your workspace or query any data.

Assign the role via the Azure CLI:

az role assignment create \
  --assignee "{CAPSULE_APP_ID}" \
  --role "Monitoring Metrics Publisher" \
  --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>"

Use the DCR resource ID from step 3 as --scope. You can pass the role by ID instead with --role 3913510d-42f4-4e42-8a64-420c390055eb.

Here you pass the application (client) ID and the CLI resolves it to the service principal for you - unlike the Quick Setup template, which needs the resolved Object ID directly because ARM can't look it up.

Verify the assignment:

az role assignment list \
  --assignee "{CAPSULE_APP_ID}" \
  --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>" \
  --query "[].{role:roleDefinitionName, scope:scope}" -o jsonc

You should see exactly one Monitoring Metrics Publisher entry whose scope is the DCR (not the resource group or subscription).

Allow a few minutes for the role assignment to propagate before testing. If a later Test Connection or first alert returns 403, the assignment hasn't propagated yet or was scoped to the wrong resource - re-run the verify command above and confirm the scope is the DCR.

Quick Setup performs this assignment for you - you only need this step in the manual flow.

5. Configure the integration in Capsule

  1. Log in to the Capsule Security portal.

  2. Go to Settings → Notifications.

  3. Find Microsoft Sentinel and click Set up.

  4. Enter the connection values:

    FieldWhere it comes from
    Directory (tenant) IDYour Microsoft Entra ID tenant ID (Entra ID → Overview)
    Data Collection Endpoint URIDCE Logs Ingestion URI (step 2)
    DCR immutable IDDCR immutable ID (step 3)
    Stream nameCustom-CapsuleAlert_CL (step 3)
  5. Click Test Connection. Capsule now sends a single [TEST] probe record through the real ingestion path - Azure access token → Data Collection Endpoint → Data Collection Rule → the CapsuleAlert_CL table - rather than just checking credentials. A passing test therefore confirms, end to end, that the credentials and token, the DCE endpoint reachability, and the DCR's Monitoring Metrics Publisher role assignment are all working: a missing role now produces a failed test (e.g. a 403) instead of a false success.

    One caveat - don't overclaim from a green check: the Logs Ingestion API returns 204 the moment it accepts the batch, and the DCR transform then runs server-side, where any field the stream's schema doesn't declare is dropped silently. A passing test proves delivery and authorization, but does not guarantee every column lands in the table. Confirm the row actually arrived with the KQL query in After Setup: Verify Data Flow. The [TEST] probe row is harmless - leave it in place or delete it; it's filterable with CapsuleAlert_CL | where Title startswith "[TEST]".

  6. Link the Sentinel destination to the policies whose violations you want forwarded.


After Setup: Verify Data Flow

Once configured, Capsule forwards alerts for linked policies as they occur. To confirm alerts are actually landing in your workspace, open Logs on your Log Analytics workspace (or Microsoft Sentinel → Logs) and run:

CapsuleAlert_CL
| sort by TimeGenerated desc
| take 50

You should see one row per forwarded alert, with columns such as Severity, Title, PolicyName, EntityName, and CapsuleTenantId.

If the query returns no rows, confirm whether the table is empty or missing:

CapsuleAlert_CL | count

A result of 0 means the table exists but no alerts have arrived yet. An error such as "failed to resolve table" means the table was never created - revisit the custom-table step (or re-run the Quick Setup template).

If you expect older alerts, widen the time range past the query window's default:

CapsuleAlert_CL
| where TimeGenerated > ago(7d)
| project TimeGenerated, Severity, Title, PolicyName, EntityName, CapsuleTenantId
| sort by TimeGenerated desc

Steady-state ingestion latency is low - Azure quotes under 10 seconds on average once data reaches the endpoint. The first alert to a brand-new table can take noticeably longer: Azure provisions a dedicated storage container the first time a custom data type appears, a one-time overhead. So if Test Connection succeeded but the table is empty right after setup, confirm an alert has fired for a linked policy, then wait a few minutes and re-run the query before troubleshooting.

From here, build Sentinel analytics rules on CapsuleAlert_CL to raise incidents from Capsule alerts.


Troubleshooting

Common Issues

  1. 403 Forbidden when sending alerts

    • The Monitoring Metrics Publisher role is not assigned to the Capsule service principal on this DCR, or the assignment hasn't propagated yet (allow a few minutes).

    • Most common cause: the role was granted to the wrong principal. If you deployed with an incorrect principalId (e.g. the application/client ID instead of the service principal Object ID), the deployment succeeds but the grant targets the wrong identity. List the assignments actually on the DCR and confirm one matches the objectId from Authorize the Capsule application:

      az role assignment list \
        --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>" \
        --query "[?roleDefinitionName=='Monitoring Metrics Publisher'].{principalId:principalId, principalType:principalType}" -o table

      If the listed principalId isn't the Capsule service principal's Object ID, re-deploy the Quick Setup template with the correct principalId (re-running is safe and idempotent) or add the grant manually with the step 4 command.

  2. 404 Not Found when sending alerts

    • The DCR immutable ID or stream name is incorrect, or the DCR isn't associated with the data collection endpoint.
  3. 401 Unauthorized

  4. Test passes, but no rows appear in CapsuleAlert_CL

    • On a brand-new table, allow a few minutes for the one-time first-appearance provisioning (see After Setup: Verify Data Flow) and confirm an alert has actually fired for a linked policy.
    • If rows still never arrive, the stream schema doesn't match the table columns, or the DCR transformation is dropping rows. Review the DCR transform and the table schema from the custom-table step.

Support

For help with this integration:

  • Email: support@capsule.security
  • Include: Your organization ID, Entra tenant ID, Log Analytics workspace ID, and any error messages

References